diff options
Diffstat (limited to 'libbcachefs/buckets.c')
-rw-r--r-- | libbcachefs/buckets.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/libbcachefs/buckets.c b/libbcachefs/buckets.c index 085e0af3..4c937199 100644 --- a/libbcachefs/buckets.c +++ b/libbcachefs/buckets.c @@ -374,6 +374,11 @@ static inline int is_fragmented_bucket(struct bucket_mark m, return 0; } +static inline int bucket_stripe_sectors(struct bucket_mark m) +{ + return m.stripe ? m.dirty_sectors : 0; +} + static inline enum bch_data_type bucket_type(struct bucket_mark m) { return m.cached_sectors && !m.dirty_sectors @@ -441,33 +446,35 @@ static void bch2_dev_usage_update(struct bch_fs *c, struct bch_dev *ca, struct bucket_mark old, struct bucket_mark new, bool gc) { - struct bch_dev_usage *dev_usage; + struct bch_dev_usage *u; percpu_rwsem_assert_held(&c->mark_lock); preempt_disable(); - dev_usage = this_cpu_ptr(ca->usage[gc]); + u = this_cpu_ptr(ca->usage[gc]); if (bucket_type(old)) - account_bucket(fs_usage, dev_usage, bucket_type(old), + account_bucket(fs_usage, u, bucket_type(old), -1, -ca->mi.bucket_size); if (bucket_type(new)) - account_bucket(fs_usage, dev_usage, bucket_type(new), + account_bucket(fs_usage, u, bucket_type(new), 1, ca->mi.bucket_size); - dev_usage->buckets_alloc += + u->buckets_alloc += (int) new.owned_by_allocator - (int) old.owned_by_allocator; - dev_usage->buckets_ec += - (int) new.stripe - (int) old.stripe; - dev_usage->buckets_unavailable += + u->buckets_unavailable += is_unavailable_bucket(new) - is_unavailable_bucket(old); - dev_usage->sectors[old.data_type] -= old.dirty_sectors; - dev_usage->sectors[new.data_type] += new.dirty_sectors; - dev_usage->sectors[BCH_DATA_CACHED] += + u->buckets_ec += (int) new.stripe - (int) old.stripe; + u->sectors_ec += bucket_stripe_sectors(new) - + bucket_stripe_sectors(old); + + u->sectors[old.data_type] -= old.dirty_sectors; + u->sectors[new.data_type] += new.dirty_sectors; + u->sectors[BCH_DATA_CACHED] += (int) new.cached_sectors - (int) old.cached_sectors; - dev_usage->sectors_fragmented += + u->sectors_fragmented += is_fragmented_bucket(new, ca) - is_fragmented_bucket(old, ca); preempt_enable(); @@ -1993,8 +2000,6 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) int ret = -ENOMEM; unsigned i; - lockdep_assert_held(&c->state_lock); - memset(&free, 0, sizeof(free)); memset(&free_inc, 0, sizeof(free_inc)); memset(&alloc_heap, 0, sizeof(alloc_heap)); @@ -2021,6 +2026,7 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) bch2_copygc_stop(ca); if (resize) { + down_write(&c->gc_lock); down_write(&ca->bucket_lock); percpu_down_write(&c->mark_lock); } @@ -2043,8 +2049,10 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) swap(ca->buckets_nouse, buckets_nouse); - if (resize) + if (resize) { percpu_up_write(&c->mark_lock); + up_write(&c->gc_lock); + } spin_lock(&c->freelist_lock); for (i = 0; i < RESERVE_NR; i++) { |