diff options
-rw-r--r-- | fs/bcachefs/bcachefs.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/buckets.c | 16 | ||||
-rw-r--r-- | fs/bcachefs/super.c | 2 |
3 files changed, 8 insertions, 11 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index 807291c33f5c..877ce788d413 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -640,6 +640,7 @@ struct bch_fs { unsigned bucket_size_max; atomic64_t sectors_available; + struct mutex sectors_available_lock; struct bch_fs_pcpu __percpu *pcpu; diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index ff4c61371830..2488a2227bd9 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -1182,13 +1182,6 @@ void bch2_trans_fs_usage_apply(struct btree_trans *trans, /* Disk reservations: */ -static u64 bch2_recalc_sectors_available(struct bch_fs *c) -{ - percpu_u64_set(&c->pcpu->sectors_available, 0); - - return avail_factor(__bch2_fs_usage_read_short(c).free); -} - void __bch2_disk_reservation_put(struct bch_fs *c, struct disk_reservation *res) { percpu_down_read(&c->mark_lock); @@ -1222,7 +1215,6 @@ int bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res, if (get < sectors) { preempt_enable(); - percpu_up_read(&c->mark_lock); goto recalculate; } } while ((v = atomic64_cmpxchg(&c->sectors_available, @@ -1240,9 +1232,10 @@ out: return 0; recalculate: - percpu_down_write(&c->mark_lock); + mutex_lock(&c->sectors_available_lock); - sectors_available = bch2_recalc_sectors_available(c); + percpu_u64_set(&c->pcpu->sectors_available, 0); + sectors_available = avail_factor(__bch2_fs_usage_read_short(c).free); if (sectors <= sectors_available || (flags & BCH_DISK_RESERVATION_NOFAIL)) { @@ -1256,7 +1249,8 @@ recalculate: ret = -ENOSPC; } - percpu_up_write(&c->mark_lock); + mutex_unlock(&c->sectors_available_lock); + percpu_up_read(&c->mark_lock); return ret; } diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index e0d4898ad0f5..b954a4e47e15 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -669,6 +669,8 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts) bch2_fs_btree_cache_init_early(&c->btree_cache); + mutex_init(&c->sectors_available_lock); + if (percpu_init_rwsem(&c->mark_lock)) goto err; |