bcachefs: Fix accounting_read when we rewind
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 25 Nov 2024 03:28:41 +0000 (22:28 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Dec 2024 06:36:19 +0000 (01:36 -0500)
If we rewind recovery to run topology repair, that causes
accounting_read to run twice.

This fixes accounting being double counted.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/disk_accounting.c

index fa821d278c45b4b9726286221384345e8d3d520c..bb5dbbf71d047df3adec7f56107948fea89641cb 100644 (file)
@@ -700,6 +700,21 @@ int bch2_accounting_read(struct bch_fs *c)
        struct btree_trans *trans = bch2_trans_get(c);
        struct printbuf buf = PRINTBUF;
 
+       /*
+        * We might run more than once if we rewind to start topology repair or
+        * btree node scan - and those might cause us to get different results,
+        * so we can't just skip if we've already run.
+        *
+        * Instead, zero out any accounting we have:
+        */
+       percpu_down_write(&c->mark_lock);
+       darray_for_each(acc->k, e)
+               percpu_memset(e->v[0], 0, sizeof(u64) * e->nr_counters);
+       for_each_member_device(c, ca)
+               percpu_memset(ca->usage, 0, sizeof(*ca->usage));
+       percpu_memset(c->usage, 0, sizeof(*c->usage));
+       percpu_up_write(&c->mark_lock);
+
        int ret = for_each_btree_key(trans, iter,
                                BTREE_ID_accounting, POS_MIN,
                                BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k, ({