diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2024-03-09 01:57:22 +0100 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-03-10 20:18:13 +0100 |
commit | ba89083e9f5d9d26f64565ec3ecb823b5bcad055 (patch) | |
tree | a4c52dd758da7c240112406eb9673d862151bcc0 /fs/bcachefs/recovery.c | |
parent | bcachefs: fix check_inode_deleted_list() (diff) | |
download | linux-ba89083e9f5d9d26f64565ec3ecb823b5bcad055.tar.xz linux-ba89083e9f5d9d26f64565ec3ecb823b5bcad055.zip |
bcachefs: Fix journal replay with unreadable btree roots
When a btree root is unreadable, we still might be able to get some data
back by replaying what's in the journal. Previously though, we got
confused when journal replay would attempt to replay a key for a level
that didn't exist.
This adds bch2_btree_increase_depth(), so that journal replay can handle
this.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to '')
-rw-r--r-- | fs/bcachefs/recovery.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index 1aa21adc7ee5..39271d2d63d1 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -124,6 +124,17 @@ static int bch2_journal_replay_key(struct btree_trans *trans, if (ret) goto out; + struct btree_path *path = btree_iter_path(trans, &iter); + if (unlikely(!btree_path_node(path, k->level))) { + bch2_trans_iter_exit(trans, &iter); + bch2_trans_node_iter_init(trans, &iter, k->btree_id, k->k->k.p, + BTREE_MAX_DEPTH, 0, iter_flags); + ret = bch2_btree_iter_traverse(&iter) ?: + bch2_btree_increase_depth(trans, iter.path, 0) ?: + -BCH_ERR_transaction_restart_nested; + goto out; + } + /* Must be checked with btree locked: */ if (k->overwritten) goto out; |