Skip to content

Commit 9104fc1

Browse files
author
Kent Overstreet
committed
bcachefs: Fix accounting read + device removal
accounting read was checking if accounting replicas entries were marked in the superblock prior to applying accounting from the journal, which meant that a recently removed device could spuriously trigger a "not marked in superblocked" error (when journal entries zero out the offending counter). Signed-off-by: Kent Overstreet <[email protected]>
1 parent 1e0272e commit 9104fc1

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

fs/bcachefs/disk_accounting.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,8 @@ int bch2_accounting_mem_insert(struct bch_fs *c, struct bkey_s_c_accounting a,
324324
{
325325
struct bch_replicas_padded r;
326326

327-
if (accounting_to_replicas(&r.e, a.k->p) &&
327+
if (mode != BCH_ACCOUNTING_read &&
328+
accounting_to_replicas(&r.e, a.k->p) &&
328329
!bch2_replicas_marked_locked(c, &r.e))
329330
return -BCH_ERR_btree_insert_need_mark_replicas;
330331

@@ -592,7 +593,6 @@ int bch2_gc_accounting_done(struct bch_fs *c)
592593
static int accounting_read_key(struct btree_trans *trans, struct bkey_s_c k)
593594
{
594595
struct bch_fs *c = trans->c;
595-
struct printbuf buf = PRINTBUF;
596596

597597
if (k.k->type != KEY_TYPE_accounting)
598598
return 0;
@@ -601,22 +601,6 @@ static int accounting_read_key(struct btree_trans *trans, struct bkey_s_c k)
601601
int ret = bch2_accounting_mem_mod_locked(trans, bkey_s_c_to_accounting(k),
602602
BCH_ACCOUNTING_read);
603603
percpu_up_read(&c->mark_lock);
604-
605-
if (bch2_accounting_key_is_zero(bkey_s_c_to_accounting(k)) &&
606-
ret == -BCH_ERR_btree_insert_need_mark_replicas)
607-
ret = 0;
608-
609-
struct disk_accounting_pos acc;
610-
bpos_to_disk_accounting_pos(&acc, k.k->p);
611-
612-
if (fsck_err_on(ret == -BCH_ERR_btree_insert_need_mark_replicas,
613-
trans, accounting_replicas_not_marked,
614-
"accounting not marked in superblock replicas\n %s",
615-
(bch2_accounting_key_to_text(&buf, &acc),
616-
buf.buf)))
617-
ret = bch2_accounting_update_sb_one(c, k.k->p);
618-
fsck_err:
619-
printbuf_exit(&buf);
620604
return ret;
621605
}
622606

@@ -628,6 +612,7 @@ int bch2_accounting_read(struct bch_fs *c)
628612
{
629613
struct bch_accounting_mem *acc = &c->accounting;
630614
struct btree_trans *trans = bch2_trans_get(c);
615+
struct printbuf buf = PRINTBUF;
631616

632617
int ret = for_each_btree_key(trans, iter,
633618
BTREE_ID_accounting, POS_MIN,
@@ -678,6 +663,30 @@ int bch2_accounting_read(struct bch_fs *c)
678663
keys->gap = keys->nr = dst - keys->data;
679664

680665
percpu_down_read(&c->mark_lock);
666+
for (unsigned i = 0; i < acc->k.nr; i++) {
667+
u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
668+
bch2_accounting_mem_read_counters(acc, i, v, ARRAY_SIZE(v), false);
669+
670+
if (bch2_is_zero(v, sizeof(v[0]) * acc->k.data[i].nr_counters))
671+
continue;
672+
673+
struct bch_replicas_padded r;
674+
675+
if (!accounting_to_replicas(&r.e, acc->k.data[i].pos))
676+
continue;
677+
678+
struct disk_accounting_pos k;
679+
bpos_to_disk_accounting_pos(&k, acc->k.data[i].pos);
680+
681+
if (fsck_err_on(!bch2_replicas_marked_locked(c, &r.e),
682+
trans, accounting_replicas_not_marked,
683+
"accounting not marked in superblock replicas\n %s",
684+
(printbuf_reset(&buf),
685+
bch2_accounting_key_to_text(&buf, &k),
686+
buf.buf)))
687+
ret = bch2_accounting_update_sb_one(c, acc->k.data[i].pos);
688+
}
689+
681690
preempt_disable();
682691
struct bch_fs_usage_base *usage = this_cpu_ptr(c->usage);
683692

@@ -713,8 +722,10 @@ int bch2_accounting_read(struct bch_fs *c)
713722
}
714723
}
715724
preempt_enable();
725+
fsck_err:
716726
percpu_up_read(&c->mark_lock);
717727
err:
728+
printbuf_exit(&buf);
718729
bch2_trans_put(trans);
719730
bch_err_fn(c, ret);
720731
return ret;

0 commit comments

Comments
 (0)