bcachefs: Simplify disk accounting validate late
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 4 Dec 2024 03:03:18 +0000 (22:03 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Dec 2024 06:36:21 +0000 (01:36 -0500)
The validate late path was iterating over accounting entries in
eytzinger order, which is unnecessarily tricky when we may have to
remove entries.

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

index 8f4c3f0665c451b7c31aa8aa83ef39332f260470..c6151495985fd79cf14671a17b0a2acd1c11f114 100644 (file)
@@ -83,7 +83,7 @@ int __bch2_darray_resize_noprof(darray_char *, size_t, size_t, gfp_t);
        for (typeof(&(_d).data[0]) _i = (_d).data; _i < (_d).data + (_d).nr; _i++)
 
 #define darray_for_each_reverse(_d, _i)                                        \
-       for (typeof(&(_d).data[0]) _i = (_d).data + (_d).nr - 1; _i >= (_d).data; --_i)
+       for (typeof(&(_d).data[0]) _i = (_d).data + (_d).nr - 1; _i >= (_d).data && (_d).nr; --_i)
 
 #define darray_init(_d)                                                        \
 do {                                                                   \
index 71c49a7ee2feb036fcede798ab4d1813c73c27fa..a915d9dc8de4b6adc124c8622938697dea1cd02b 100644 (file)
@@ -765,15 +765,16 @@ int bch2_accounting_read(struct bch_fs *c)
        keys->gap = keys->nr = dst - keys->data;
 
        percpu_down_write(&c->mark_lock);
-       unsigned i = 0;
-       while (i < acc->k.nr) {
-               unsigned idx = inorder_to_eytzinger0(i, acc->k.nr);
 
+       darray_for_each_reverse(acc->k, i) {
                struct disk_accounting_pos acc_k;
-               bpos_to_disk_accounting_pos(&acc_k, acc->k.data[idx].pos);
+               bpos_to_disk_accounting_pos(&acc_k, i->pos);
 
                u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
-               bch2_accounting_mem_read_counters(acc, idx, v, ARRAY_SIZE(v), false);
+               memset(v, 0, sizeof(v));
+
+               for (unsigned j = 0; j < i->nr_counters; j++)
+                       v[j] = percpu_u64_get(i->v[0] + j);
 
                /*
                 * If the entry counters are zeroed, it should be treated as
@@ -782,26 +783,25 @@ int bch2_accounting_read(struct bch_fs *c)
                 * Remove it, so that if it's re-added it gets re-marked in the
                 * superblock:
                 */
-               ret = bch2_is_zero(v, sizeof(v[0]) * acc->k.data[idx].nr_counters)
+               ret = bch2_is_zero(v, sizeof(v[0]) * i->nr_counters)
                        ? -BCH_ERR_remove_disk_accounting_entry
-                       : bch2_disk_accounting_validate_late(trans, acc_k,
-                                                       v, acc->k.data[idx].nr_counters);
+                       : bch2_disk_accounting_validate_late(trans, acc_k, v, i->nr_counters);
 
                if (ret == -BCH_ERR_remove_disk_accounting_entry) {
-                       free_percpu(acc->k.data[idx].v[0]);
-                       free_percpu(acc->k.data[idx].v[1]);
-                       darray_remove_item(&acc->k, &acc->k.data[idx]);
-                       eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
-                                       accounting_pos_cmp, NULL);
+                       free_percpu(i->v[0]);
+                       free_percpu(i->v[1]);
+                       darray_remove_item(&acc->k, i);
                        ret = 0;
                        continue;
                }
 
                if (ret)
                        goto fsck_err;
-               i++;
        }
 
+       eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
+                       accounting_pos_cmp, NULL);
+
        preempt_disable();
        struct bch_fs_usage_base *usage = this_cpu_ptr(c->usage);