summaryrefslogtreecommitdiff
path: root/fs/bcachefs/recovery.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-03-15 22:32:03 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:37 -0400
commitf44a6a7134371d8b1e14055a2705d0f4da4c46d6 (patch)
treeb69c6ca3d039acc14494bce89c5871fc60d4fd67 /fs/bcachefs/recovery.c
parente62d65f2fbc3cb89ffd273ec0931ff32b778ef8b (diff)
downloadlwn-f44a6a7134371d8b1e14055a2705d0f4da4c46d6.tar.gz
lwn-f44a6a7134371d8b1e14055a2705d0f4da4c46d6.zip
bcachefs: Replay interior node keys
This slightly modifies the journal replay code so that it can replay updates to interior nodes. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/recovery.c')
-rw-r--r--fs/bcachefs/recovery.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index 0d4abaa3ba10..b4d9e1f98059 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -230,9 +230,9 @@ static int journal_sort_seq_cmp(const void *_l, const void *_r)
const struct journal_key *l = _l;
const struct journal_key *r = _r;
- return cmp_int(l->journal_seq, r->journal_seq) ?:
+ return cmp_int(r->level, l->level) ?:
+ cmp_int(l->journal_seq, r->journal_seq) ?:
cmp_int(l->btree_id, r->btree_id) ?:
- cmp_int(l->level, r->level) ?:
bkey_cmp(l->k->k.p, r->k->k.p);
}
@@ -404,12 +404,15 @@ err:
}
static int __bch2_journal_replay_key(struct btree_trans *trans,
- enum btree_id id, struct bkey_i *k)
+ enum btree_id id, unsigned level,
+ struct bkey_i *k)
{
struct btree_iter *iter;
int ret;
- iter = bch2_trans_get_iter(trans, id, k->k.p, BTREE_ITER_INTENT);
+ iter = bch2_trans_get_node_iter(trans, id, k->k.p,
+ BTREE_MAX_DEPTH, level,
+ BTREE_ITER_INTENT);
if (IS_ERR(iter))
return PTR_ERR(iter);
@@ -428,13 +431,13 @@ static int __bch2_journal_replay_key(struct btree_trans *trans,
}
static int bch2_journal_replay_key(struct bch_fs *c, enum btree_id id,
- struct bkey_i *k)
+ unsigned level, struct bkey_i *k)
{
return bch2_trans_do(c, NULL, NULL,
BTREE_INSERT_NOFAIL|
BTREE_INSERT_LAZY_RW|
BTREE_INSERT_JOURNAL_REPLAY,
- __bch2_journal_replay_key(&trans, id, k));
+ __bch2_journal_replay_key(&trans, id, level, k));
}
static int bch2_journal_replay(struct bch_fs *c,
@@ -446,15 +449,20 @@ static int bch2_journal_replay(struct bch_fs *c,
sort(keys.d, keys.nr, sizeof(keys.d[0]), journal_sort_seq_cmp, NULL);
+ replay_now_at(j, keys.journal_seq_base);
+
for_each_journal_key(keys, i) {
- replay_now_at(j, keys.journal_seq_base + i->journal_seq);
+ if (!i->level)
+ replay_now_at(j, keys.journal_seq_base + i->journal_seq);
+ if (i->level)
+ ret = bch2_journal_replay_key(c, i->btree_id, i->level, i->k);
if (i->btree_id == BTREE_ID_ALLOC)
ret = bch2_alloc_replay_key(c, i->k);
else if (i->k->k.size)
ret = bch2_extent_replay_key(c, i->btree_id, i->k);
else
- ret = bch2_journal_replay_key(c, i->btree_id, i->k);
+ ret = bch2_journal_replay_key(c, i->btree_id, i->level, i->k);
if (ret) {
bch_err(c, "journal replay: error %d while replaying key",