summaryrefslogtreecommitdiff
path: root/fs/bcachefs/recovery.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2022-04-11 20:28:13 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:31 -0400
commit5650bb46be89a1254609d47e4c87d1e9cf9121fb (patch)
tree73506214235f46eed04b2e4675463db1b38b2ea4 /fs/bcachefs/recovery.c
parent9b93596c33f6c23de96c05dce82b9aead271a286 (diff)
downloadlwn-5650bb46be89a1254609d47e4c87d1e9cf9121fb.tar.gz
lwn-5650bb46be89a1254609d47e4c87d1e9cf9121fb.zip
bcachefs: Introduce bch2_journal_keys_peek_(upto|slot)()
When many journal replay keys have been overwritten, bch2_journal_keys_peek() was taking excessively long to scan before it found a key to return. Fix this by introducing bch2_journal_keys_peek_upto() which takes a parameter for the end of the range we want, so that we can terminate the search much sooner, and replace all uses of bch2_journal_keys_peek() with peek_upto() or peek_slot(). Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/recovery.c')
-rw-r--r--fs/bcachefs/recovery.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index 9269cb686e4d..16ba5d24a86d 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -109,26 +109,34 @@ size_t bch2_journal_key_search(struct journal_keys *keys,
return idx_to_pos(keys, l);
}
-struct bkey_i *bch2_journal_keys_peek(struct bch_fs *c, enum btree_id btree_id,
- unsigned level, struct bpos pos)
+struct bkey_i *bch2_journal_keys_peek_upto(struct bch_fs *c, enum btree_id btree_id,
+ unsigned level, struct bpos pos,
+ struct bpos end_pos)
{
struct journal_keys *keys = &c->journal_keys;
size_t idx = bch2_journal_key_search(keys, btree_id, level, pos);
while (idx < keys->size &&
- keys->d[idx].overwritten) {
+ keys->d[idx].btree_id == btree_id &&
+ keys->d[idx].level == level &&
+ bpos_cmp(keys->d[idx].k->k.p, end_pos) <= 0) {
+ if (!keys->d[idx].overwritten)
+ return keys->d[idx].k;
+
idx++;
if (idx == keys->gap)
idx += keys->size - keys->nr;
}
- if (idx < keys->size &&
- keys->d[idx].btree_id == btree_id &&
- keys->d[idx].level == level)
- return keys->d[idx].k;
return NULL;
}
+struct bkey_i *bch2_journal_keys_peek_slot(struct bch_fs *c, enum btree_id btree_id,
+ unsigned level, struct bpos pos)
+{
+ return bch2_journal_keys_peek_upto(c, btree_id, level, pos, pos);
+}
+
static void journal_iters_fix(struct bch_fs *c)
{
struct journal_keys *keys = &c->journal_keys;