diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2024-02-23 19:16:19 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-04-30 00:48:33 -0400 |
commit | b5c9eaf932b07bdfcfa6d8f46b30188459968cd0 (patch) | |
tree | 6f30df5dba2cda593f96f3783298262b4ba9f8d7 | |
parent | 0c718f19e3d3746c683a7f07b41b38f4674fe6c3 (diff) |
fixup bcachefs: bch2_verify_accounting_clean()bcachefs-disk-accounting-rewrite
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/disk_accounting.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/fs/bcachefs/disk_accounting.c b/fs/bcachefs/disk_accounting.c index e0427cfa99f6..d7ff6e312eb8 100644 --- a/fs/bcachefs/disk_accounting.c +++ b/fs/bcachefs/disk_accounting.c @@ -586,6 +586,7 @@ int bch2_dev_usage_init(struct bch_dev *ca, bool gc) void bch2_verify_accounting_clean(struct bch_fs *c) { bool mismatch = false; + struct bch_fs_usage_base base = {}, base_inmem = {}; bch2_trans_run(c, for_each_btree_key(trans, iter, @@ -609,10 +610,59 @@ void bch2_verify_accounting_clean(struct bch_fs *c) printbuf_exit(&buf); mismatch = true; } + + struct disk_accounting_pos acc_k; + bpos_to_disk_accounting_pos(&acc_k, a.k->p); + + switch (acc_k.type) { + case BCH_DISK_ACCOUNTING_persistent_reserved: + base.reserved += acc_k.persistent_reserved.nr_replicas * a.v->d[0]; + break; + case BCH_DISK_ACCOUNTING_replicas: + fs_usage_data_type_to_base(&base, acc_k.replicas.data_type, a.v->d[0]); + break; + case BCH_DISK_ACCOUNTING_dev_data_type: { + struct bch_dev *ca = bch2_dev_bkey_exists(c, acc_k.dev_data_type.dev); + + v[0] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].buckets); + v[1] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].sectors); + v[2] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].fragmented); + + if (memcmp(a.v->d, v, 3 * sizeof(u64))) { + struct printbuf buf = PRINTBUF; + + bch2_bkey_val_to_text(&buf, c, k); + prt_str(&buf, " in mem"); + for (unsigned j = 0; j < nr; j++) + prt_printf(&buf, " %llu", v[j]); + + pr_err("dev accounting mismatch: %s", buf.buf); + printbuf_exit(&buf); + mismatch = true; + } + } + } + 0; }))); - WARN_ON(mismatch); + acc_u64s_percpu(&base_inmem.hidden, &c->usage->hidden, sizeof(base_inmem) / sizeof(u64)); + +#define check(x) \ + if (base.x != base_inmem.x) { \ + pr_err("fs_usage_base.%s mismatch: %llu != %llu", #x, base.x, base_inmem.x); \ + mismatch = true; \ + } + + //check(hidden); + check(btree); + check(data); + check(cached); + check(reserved); + check(nr_inodes); + + if (mismatch) + panic("\n"); } void bch2_accounting_free(struct bch_accounting_mem *acc) |