bcachefs: Fix btree for nonexistent tree depth

The fix for when we should increase tree depth in journal replay was
entirely bogus.

We should only increase the tree depth in journal replay when recovery
from btree node scan, and then only for keys found by btree node scan.

This needs additional work - we should be shooting down existing
interior node pointers when recovery from scan, they shouldn't be
showing up here.

Fixes: b47a82ff47 ("bcachefs: Only run 'increase_depth' for keys from btree node csan")
Cc: Alan Huang <mmpgouride@gmail.com>
Reported-by: syzbot+8deb6ff4415db67a9f18@syzkaller.appspotmail.com
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2025-07-03 15:53:51 -04:00
parent ddb9680a72
commit c72d628469

View file

@ -273,24 +273,35 @@ static int bch2_journal_replay_key(struct btree_trans *trans,
goto out; goto out;
struct btree_path *path = btree_iter_path(trans, &iter); struct btree_path *path = btree_iter_path(trans, &iter);
if (unlikely(!btree_path_node(path, k->level) && if (unlikely(!btree_path_node(path, k->level))) {
!k->allocated)) {
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
CLASS(printbuf, buf)();
prt_str(&buf, "btree=");
bch2_btree_id_to_text(&buf, k->btree_id);
prt_printf(&buf, " level=%u ", k->level);
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(k->k));
if (!(c->recovery.passes_complete & (BIT_ULL(BCH_RECOVERY_PASS_scan_for_btree_nodes)| if (!(c->recovery.passes_complete & (BIT_ULL(BCH_RECOVERY_PASS_scan_for_btree_nodes)|
BIT_ULL(BCH_RECOVERY_PASS_check_topology)))) { BIT_ULL(BCH_RECOVERY_PASS_check_topology)))) {
bch_err(c, "have key in journal replay for btree depth that does not exist, confused"); bch_err(c, "have key in journal replay for btree depth that does not exist, confused\n%s",
buf.buf);
ret = -EINVAL; ret = -EINVAL;
} }
#if 0
if (!k->allocated) {
bch_notice(c, "dropping key in journal replay for depth that does not exist because we're recovering from scan\n%s",
buf.buf);
k->overwritten = true;
goto out;
}
bch2_trans_iter_exit(trans, &iter); bch2_trans_iter_exit(trans, &iter);
bch2_trans_node_iter_init(trans, &iter, k->btree_id, k->k->k.p, bch2_trans_node_iter_init(trans, &iter, k->btree_id, k->k->k.p,
BTREE_MAX_DEPTH, 0, iter_flags); BTREE_MAX_DEPTH, 0, iter_flags);
ret = bch2_btree_iter_traverse(trans, &iter) ?: ret = bch2_btree_iter_traverse(trans, &iter) ?:
bch2_btree_increase_depth(trans, iter.path, 0) ?: bch2_btree_increase_depth(trans, iter.path, 0) ?:
-BCH_ERR_transaction_restart_nested; -BCH_ERR_transaction_restart_nested;
#endif
k->overwritten = true;
goto out; goto out;
} }