mirror of
https://github.com/torvalds/linux.git
synced 2025-08-16 06:31:34 +02:00
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:
parent
ddb9680a72
commit
c72d628469
1 changed files with 17 additions and 6 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue