Skip to content

Commit 3e72acb

Browse files
author
Kent Overstreet
committed
bcachefs: Ensure btree node scan runs before checking for scanned nodes
Previously, calling bch2_btree_has_scanned_nodes() when btree node scan hadn't actually run would erroniously return false - causing us to think a btree was entirely gone. This fixes a 6.16 regression from moving the scheduling of btree node scan out of bch2_btree_lost_data() (fixing the bug where we'd schedule it persistently in the superblock) and only scheduling it when check_toploogy() is asking for scanned btree nodes. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 1dcea07 commit 3e72acb

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

fs/bcachefs/btree_gc.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -534,32 +534,39 @@ static int bch2_btree_repair_topology_recurse(struct btree_trans *trans, struct
534534
return ret;
535535
}
536536

537-
static int bch2_check_root(struct btree_trans *trans, enum btree_id i,
537+
static int bch2_check_root(struct btree_trans *trans, enum btree_id btree,
538538
bool *reconstructed_root)
539539
{
540540
struct bch_fs *c = trans->c;
541-
struct btree_root *r = bch2_btree_id_root(c, i);
541+
struct btree_root *r = bch2_btree_id_root(c, btree);
542542
struct printbuf buf = PRINTBUF;
543543
int ret = 0;
544544

545-
bch2_btree_id_to_text(&buf, i);
545+
bch2_btree_id_to_text(&buf, btree);
546546

547547
if (r->error) {
548548
bch_info(c, "btree root %s unreadable, must recover from scan", buf.buf);
549549

550-
r->alive = false;
551-
r->error = 0;
550+
ret = bch2_btree_has_scanned_nodes(c, btree);
551+
if (ret < 0)
552+
goto err;
552553

553-
if (!bch2_btree_has_scanned_nodes(c, i)) {
554+
if (!ret) {
554555
__fsck_err(trans,
555-
FSCK_CAN_FIX|(!btree_id_important(i) ? FSCK_AUTOFIX : 0),
556+
FSCK_CAN_FIX|(!btree_id_important(btree) ? FSCK_AUTOFIX : 0),
556557
btree_root_unreadable_and_scan_found_nothing,
557558
"no nodes found for btree %s, continue?", buf.buf);
558-
bch2_btree_root_alloc_fake_trans(trans, i, 0);
559+
560+
r->alive = false;
561+
r->error = 0;
562+
bch2_btree_root_alloc_fake_trans(trans, btree, 0);
559563
} else {
560-
bch2_btree_root_alloc_fake_trans(trans, i, 1);
561-
bch2_shoot_down_journal_keys(c, i, 1, BTREE_MAX_DEPTH, POS_MIN, SPOS_MAX);
562-
ret = bch2_get_scanned_nodes(c, i, 0, POS_MIN, SPOS_MAX);
564+
r->alive = false;
565+
r->error = 0;
566+
bch2_btree_root_alloc_fake_trans(trans, btree, 1);
567+
568+
bch2_shoot_down_journal_keys(c, btree, 1, BTREE_MAX_DEPTH, POS_MIN, SPOS_MAX);
569+
ret = bch2_get_scanned_nodes(c, btree, 0, POS_MIN, SPOS_MAX);
563570
if (ret)
564571
goto err;
565572
}

fs/bcachefs/btree_node_scan.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,8 +521,12 @@ bool bch2_btree_node_is_stale(struct bch_fs *c, struct btree *b)
521521
return false;
522522
}
523523

524-
bool bch2_btree_has_scanned_nodes(struct bch_fs *c, enum btree_id btree)
524+
int bch2_btree_has_scanned_nodes(struct bch_fs *c, enum btree_id btree)
525525
{
526+
int ret = bch2_run_print_explicit_recovery_pass(c, BCH_RECOVERY_PASS_scan_for_btree_nodes);
527+
if (ret)
528+
return ret;
529+
526530
struct found_btree_node search = {
527531
.btree_id = btree,
528532
.level = 0,

fs/bcachefs/btree_node_scan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
int bch2_scan_for_btree_nodes(struct bch_fs *);
66
bool bch2_btree_node_is_stale(struct bch_fs *, struct btree *);
7-
bool bch2_btree_has_scanned_nodes(struct bch_fs *, enum btree_id);
7+
int bch2_btree_has_scanned_nodes(struct bch_fs *, enum btree_id);
88
int bch2_get_scanned_nodes(struct bch_fs *, enum btree_id, unsigned, struct bpos, struct bpos);
99
void bch2_find_btree_nodes_exit(struct find_btree_nodes *);
1010

0 commit comments

Comments
 (0)