Skip to content

Commit 5668e5d

Browse files
author
Kent Overstreet
committed
bcachefs: bch2_verify_accounting_clean()
Verify that the in-memory accounting verifies the on-disk accounting after a clean shutdown. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 00839ad commit 5668e5d

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

fs/bcachefs/disk_accounting.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,93 @@ int bch2_dev_usage_init(struct bch_dev *ca, bool gc)
588588
return ret;
589589
}
590590

591+
void bch2_verify_accounting_clean(struct bch_fs *c)
592+
{
593+
bool mismatch = false;
594+
struct bch_fs_usage_base base = {}, base_inmem = {};
595+
596+
bch2_trans_run(c,
597+
for_each_btree_key(trans, iter,
598+
BTREE_ID_accounting, POS_MIN,
599+
BTREE_ITER_all_snapshots, k, ({
600+
u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
601+
struct bkey_s_c_accounting a = bkey_s_c_to_accounting(k);
602+
unsigned nr = bch2_accounting_counters(k.k);
603+
604+
bch2_accounting_mem_read(c, k.k->p, v, nr);
605+
606+
if (memcmp(a.v->d, v, nr * sizeof(u64))) {
607+
struct printbuf buf = PRINTBUF;
608+
609+
bch2_bkey_val_to_text(&buf, c, k);
610+
prt_str(&buf, " !=");
611+
for (unsigned j = 0; j < nr; j++)
612+
prt_printf(&buf, " %llu", v[j]);
613+
614+
pr_err("%s", buf.buf);
615+
printbuf_exit(&buf);
616+
mismatch = true;
617+
}
618+
619+
struct disk_accounting_pos acc_k;
620+
bpos_to_disk_accounting_pos(&acc_k, a.k->p);
621+
622+
switch (acc_k.type) {
623+
case BCH_DISK_ACCOUNTING_persistent_reserved:
624+
base.reserved += acc_k.persistent_reserved.nr_replicas * a.v->d[0];
625+
break;
626+
case BCH_DISK_ACCOUNTING_replicas:
627+
fs_usage_data_type_to_base(&base, acc_k.replicas.data_type, a.v->d[0]);
628+
break;
629+
case BCH_DISK_ACCOUNTING_dev_data_type: {
630+
rcu_read_lock();
631+
struct bch_dev *ca = bch2_dev_rcu(c, acc_k.dev_data_type.dev);
632+
if (!ca) {
633+
rcu_read_unlock();
634+
continue;
635+
}
636+
637+
v[0] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].buckets);
638+
v[1] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].sectors);
639+
v[2] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].fragmented);
640+
rcu_read_unlock();
641+
642+
if (memcmp(a.v->d, v, 3 * sizeof(u64))) {
643+
struct printbuf buf = PRINTBUF;
644+
645+
bch2_bkey_val_to_text(&buf, c, k);
646+
prt_str(&buf, " in mem");
647+
for (unsigned j = 0; j < nr; j++)
648+
prt_printf(&buf, " %llu", v[j]);
649+
650+
pr_err("dev accounting mismatch: %s", buf.buf);
651+
printbuf_exit(&buf);
652+
mismatch = true;
653+
}
654+
}
655+
}
656+
657+
0;
658+
})));
659+
660+
acc_u64s_percpu(&base_inmem.hidden, &c->usage->hidden, sizeof(base_inmem) / sizeof(u64));
661+
662+
#define check(x) \
663+
if (base.x != base_inmem.x) { \
664+
pr_err("fs_usage_base.%s mismatch: %llu != %llu", #x, base.x, base_inmem.x); \
665+
mismatch = true; \
666+
}
667+
668+
//check(hidden);
669+
check(btree);
670+
check(data);
671+
check(cached);
672+
check(reserved);
673+
check(nr_inodes);
674+
675+
WARN_ON(mismatch);
676+
}
677+
591678
void bch2_accounting_free(struct bch_accounting_mem *acc)
592679
{
593680
darray_exit(&acc->k);

fs/bcachefs/disk_accounting.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ static inline void bch2_accounting_mem_read_counters(struct bch_fs *c, unsigned
171171
{
172172
memset(v, 0, sizeof(*v) * nr);
173173

174-
struct bch_accounting_mem *acc = &c->accounting[0];
174+
struct bch_accounting_mem *acc = &c->accounting[gc];
175175
if (unlikely(idx >= acc->k.nr))
176176
return;
177177

@@ -201,6 +201,8 @@ int bch2_accounting_read(struct bch_fs *);
201201
int bch2_dev_usage_remove(struct bch_fs *, unsigned);
202202
int bch2_dev_usage_init(struct bch_dev *, bool);
203203

204+
void bch2_verify_accounting_clean(struct bch_fs *c);
205+
204206
void bch2_accounting_free(struct bch_accounting_mem *);
205207
void bch2_fs_accounting_exit(struct bch_fs *);
206208

fs/bcachefs/super.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ void bch2_fs_read_only(struct bch_fs *c)
361361
BUG_ON(atomic_long_read(&c->btree_key_cache.nr_dirty));
362362
BUG_ON(c->btree_write_buffer.inc.keys.nr);
363363
BUG_ON(c->btree_write_buffer.flushing.keys.nr);
364+
bch2_verify_accounting_clean(c);
364365

365366
bch_verbose(c, "marking filesystem clean");
366367
bch2_fs_mark_clean(c);

0 commit comments

Comments
 (0)