bcachefs: fs_usage_u64s()
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 15 Feb 2019 01:39:17 +0000 (20:39 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:16 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_gc.c
fs/bcachefs/buckets.c
fs/bcachefs/buckets.h
fs/bcachefs/replicas.c
fs/bcachefs/super.c

index 5091966b7b5426f2b209b867d782d4eb0a330308..56402fc64bc22f881ac5563c34df2a1d311d9373 100644 (file)
@@ -605,8 +605,7 @@ static void bch2_gc_done(struct bch_fs *c, bool initial)
        }
 
        {
-               unsigned nr = sizeof(struct bch_fs_usage) / sizeof(u64) +
-                       c->replicas.nr;
+               unsigned nr = fs_usage_u64s(c);
                struct bch_fs_usage *dst = (void *)
                        bch2_acc_percpu_u64s((void *) c->usage[0], nr);
                struct bch_fs_usage *src = (void *)
@@ -657,10 +656,8 @@ static int bch2_gc_start(struct bch_fs *c)
 
        BUG_ON(c->usage[1]);
 
-       c->usage[1] = __alloc_percpu_gfp(sizeof(struct bch_fs_usage) +
-                                        sizeof(u64) * c->replicas.nr,
-                                        sizeof(u64),
-                                        GFP_KERNEL);
+       c->usage[1] = __alloc_percpu_gfp(fs_usage_u64s(c) * sizeof(u64),
+                                        sizeof(u64), GFP_KERNEL);
        percpu_up_write(&c->mark_lock);
 
        if (!c->usage[1])
index ac54d82f9e110cd70477ae26311a3bb5ab7cd3c8..5011e7af3563ecc1dcb708cacd410c7bcf5cf116 100644 (file)
@@ -117,11 +117,11 @@ void bch2_bucket_seq_cleanup(struct bch_fs *c)
 void bch2_fs_usage_initialize(struct bch_fs *c)
 {
        struct bch_fs_usage *usage;
-       unsigned i, nr;
+       unsigned i;
 
        percpu_down_write(&c->mark_lock);
-       nr = sizeof(struct bch_fs_usage) / sizeof(u64) + c->replicas.nr;
-       usage = (void *) bch2_acc_percpu_u64s((void *) c->usage[0], nr);
+       usage = (void *) bch2_acc_percpu_u64s((void *) c->usage[0],
+                                             fs_usage_u64s(c));
 
        for (i = 0; i < BCH_REPLICAS_MAX; i++)
                usage->reserved += usage->persistent_reserved[i];
@@ -159,24 +159,23 @@ struct bch_dev_usage bch2_dev_usage_read(struct bch_fs *c, struct bch_dev *ca)
 struct bch_fs_usage *bch2_fs_usage_read(struct bch_fs *c)
 {
        struct bch_fs_usage *ret;
-       unsigned nr = READ_ONCE(c->replicas.nr);
+       unsigned v, u64s = fs_usage_u64s(c);
 retry:
-       ret = kzalloc(sizeof(*ret) + nr * sizeof(u64), GFP_NOFS);
+       ret = kzalloc(u64s * sizeof(u64), GFP_NOFS);
        if (unlikely(!ret))
                return NULL;
 
        percpu_down_read(&c->mark_lock);
 
-       if (unlikely(nr < c->replicas.nr)) {
-               nr = c->replicas.nr;
+       v = fs_usage_u64s(c);
+       if (unlikely(u64s != v)) {
+               u64s = v;
                percpu_up_read(&c->mark_lock);
                kfree(ret);
                goto retry;
        }
 
-       acc_u64s_percpu((u64 *) ret,
-                       (u64 __percpu *) c->usage[0],
-                       sizeof(*ret) / sizeof(u64) + nr);
+       acc_u64s_percpu((u64 *) ret, (u64 __percpu *) c->usage[0], u64s);
 
        return ret;
 }
@@ -294,8 +293,7 @@ int bch2_fs_usage_apply(struct bch_fs *c,
 
        preempt_disable();
        acc_u64s((u64 *) this_cpu_ptr(c->usage[0]),
-                (u64 *) fs_usage,
-                sizeof(*fs_usage) / sizeof(u64) + c->replicas.nr);
+                (u64 *) fs_usage, fs_usage_u64s(c));
        preempt_enable();
 
        return ret;
index 67a1d17610f3ce34221bfdcf9cb1317a96ccaac8..5f0b5a6ec9ad5dfb16a29edc40ad23dfca6b1670 100644 (file)
@@ -212,14 +212,18 @@ static inline u64 dev_buckets_free(struct bch_fs *c, struct bch_dev *ca)
 
 /* Filesystem usage: */
 
-static inline struct bch_fs_usage *bch2_fs_usage_get_scratch(struct bch_fs *c)
+static inline unsigned fs_usage_u64s(struct bch_fs *c)
 {
-       struct bch_fs_usage *ret;
 
-       ret = this_cpu_ptr(c->usage_scratch);
+       return sizeof(struct bch_fs_usage) / sizeof(u64) +
+               READ_ONCE(c->replicas.nr);
+}
 
-       memset(ret, 0, sizeof(*ret) + c->replicas.nr * sizeof(u64));
+static inline struct bch_fs_usage *bch2_fs_usage_get_scratch(struct bch_fs *c)
+{
+       struct bch_fs_usage *ret = this_cpu_ptr(c->usage_scratch);
 
+       memset(ret, 0, fs_usage_u64s(c) * sizeof(u64));
        return ret;
 }
 
index 03bb6b51d15fe61c331dc1734de2815a8f30017b..72592df9afc0d699df807093b4e3e2d35814829f 100644 (file)
@@ -262,39 +262,37 @@ static void __replicas_table_update(struct bch_fs_usage __percpu *dst_p,
 static int replicas_table_update(struct bch_fs *c,
                                 struct bch_replicas_cpu *new_r)
 {
-       struct bch_fs_usage __percpu *new_usage[3] = { NULL, NULL, NULL };
+       struct bch_fs_usage __percpu *new_usage[2] = { NULL, NULL };
+       struct bch_fs_usage __percpu *new_scratch = NULL;
        unsigned bytes = sizeof(struct bch_fs_usage) +
                sizeof(u64) * new_r->nr;
-       unsigned i;
        int ret = -ENOMEM;
 
-       for (i = 0; i < 3; i++) {
-               if (i < 2 && !c->usage[i])
-                       continue;
-
-               new_usage[i] = __alloc_percpu_gfp(bytes, sizeof(u64),
-                                                 GFP_NOIO);
-               if (!new_usage[i])
-                       goto err;
-       }
-
-       for (i = 0; i < 2; i++) {
-               if (!c->usage[i])
-                       continue;
-
-               __replicas_table_update(new_usage[i],   new_r,
-                                       c->usage[i],    &c->replicas);
-
-               swap(c->usage[i], new_usage[i]);
-       }
-
-       swap(c->usage_scratch, new_usage[2]);
+       if (!(new_usage[0] = __alloc_percpu_gfp(bytes, sizeof(u64),
+                                               GFP_NOIO)) ||
+           (c->usage[1] &&
+            !(new_usage[1] = __alloc_percpu_gfp(bytes, sizeof(u64),
+                                                GFP_NOIO))) ||
+           !(new_scratch  = __alloc_percpu_gfp(bytes, sizeof(u64),
+                                               GFP_NOIO)))
+               goto err;
 
-       swap(c->replicas, *new_r);
+       if (c->usage[0])
+               __replicas_table_update(new_usage[0],   new_r,
+                                       c->usage[0],    &c->replicas);
+       if (c->usage[1])
+               __replicas_table_update(new_usage[1],   new_r,
+                                       c->usage[1],    &c->replicas);
+
+       swap(c->usage[0],       new_usage[0]);
+       swap(c->usage[1],       new_usage[1]);
+       swap(c->usage_scratch,  new_scratch);
+       swap(c->replicas,       *new_r);
        ret = 0;
 err:
-       for (i = 0; i < 3; i++)
-               free_percpu(new_usage[i]);
+       free_percpu(new_scratch);
+       free_percpu(new_usage[1]);
+       free_percpu(new_usage[0]);
        return ret;
 }
 
@@ -975,5 +973,6 @@ int bch2_fs_replicas_init(struct bch_fs *c)
 {
        c->journal.entry_u64s_reserved +=
                reserve_journal_replicas(c, &c->replicas);
-       return 0;
+
+       return replicas_table_update(c, &c->replicas);
 }
index 29cb12d841e719fe039b86f1f161c772f6973a86..be8c4a604d8c6dc64e37417a475e6a804e5b4da0 100644 (file)
@@ -535,7 +535,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
 {
        struct bch_sb_field_members *mi;
        struct bch_fs *c;
-       unsigned i, iter_size, fs_usage_size;
+       unsigned i, iter_size;
        const char *err;
 
        pr_verbose_init(opts, "");
@@ -629,9 +629,6 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
                (btree_blocks(c) + 1) * 2 *
                sizeof(struct btree_node_iter_set);
 
-       fs_usage_size = sizeof(struct bch_fs_usage) +
-               sizeof(u64) * c->replicas.nr;
-
        if (!(c->wq = alloc_workqueue("bcachefs",
                                WQ_FREEZABLE|WQ_MEM_RECLAIM|WQ_HIGHPRI, 1)) ||
            !(c->copygc_wq = alloc_workqueue("bcache_copygc",
@@ -648,8 +645,6 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
                        max(offsetof(struct btree_read_bio, bio),
                            offsetof(struct btree_write_bio, wbio.bio)),
                        BIOSET_NEED_BVECS) ||
-           !(c->usage[0] = __alloc_percpu(fs_usage_size, sizeof(u64))) ||
-           !(c->usage_scratch = __alloc_percpu(fs_usage_size, sizeof(u64))) ||
            !(c->pcpu = alloc_percpu(struct bch_fs_pcpu)) ||
            mempool_init_kvpmalloc_pool(&c->btree_bounce_pool, 1,
                                        btree_bytes(c)) ||