diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2020-03-15 22:32:03 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:37 -0400 |
commit | f44a6a7134371d8b1e14055a2705d0f4da4c46d6 (patch) | |
tree | b69c6ca3d039acc14494bce89c5871fc60d4fd67 /fs/bcachefs/recovery.c | |
parent | e62d65f2fbc3cb89ffd273ec0931ff32b778ef8b (diff) | |
download | lwn-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.c | 24 |
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", |