diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-04-11 20:28:13 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:31 -0400 |
commit | 5650bb46be89a1254609d47e4c87d1e9cf9121fb (patch) | |
tree | 73506214235f46eed04b2e4675463db1b38b2ea4 /fs/bcachefs/recovery.c | |
parent | 9b93596c33f6c23de96c05dce82b9aead271a286 (diff) | |
download | lwn-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.c | 22 |
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; |