diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-12-17 00:57:37 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-01-01 11:47:44 -0500 |
commit | 359e89add5b89fb467f08391ab9d80ba6e775295 (patch) | |
tree | c3ea40db7931b4e13bb4f3a55c2394534b22faa2 | |
parent | eb6863598a9dff88bdb4483cc09a3ec8e1150b48 (diff) | |
download | lwn-359e89add5b89fb467f08391ab9d80ba6e775295.tar.gz lwn-359e89add5b89fb467f08391ab9d80ba6e775295.zip |
bcachefs: bch2_btree_trans_peek_prev_updates
bch2_btree_iter_peek_prev() now supports BTREE_ITER_WITH_UPDATES
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/btree_iter.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index 1d2be541d5a2..a5a0c8e77930 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -1888,6 +1888,22 @@ inline bool bch2_btree_iter_rewind(struct btree_iter *iter) } static noinline +void bch2_btree_trans_peek_prev_updates(struct btree_trans *trans, struct btree_iter *iter, + struct bkey_s_c *k) +{ + struct bpos end = path_l(btree_iter_path(trans, iter))->b->data->min_key; + + trans_for_each_update(trans, i) + if (!i->key_cache_already_flushed && + i->btree_id == iter->btree_id && + bpos_le(i->k->k.p, iter->pos) && + bpos_ge(i->k->k.p, k->k ? k->k->p : end)) { + iter->k = i->k->k; + *k = bkey_i_to_s_c(i->k); + } +} + +static noinline void bch2_btree_trans_peek_updates(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c *k) { @@ -2302,7 +2318,6 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter) EBUG_ON(btree_iter_path(trans, iter)->cached || btree_iter_path(trans, iter)->level); - EBUG_ON(iter->flags & BTREE_ITER_WITH_UPDATES); if (iter->flags & BTREE_ITER_WITH_JOURNAL) return bkey_s_c_err(-EIO); @@ -2335,6 +2350,10 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter) : bpos_gt(k.k->p, search_key))) k = btree_path_level_prev(trans, path, &path->l[0], &iter->k); + if (unlikely((iter->flags & BTREE_ITER_WITH_UPDATES) && + trans->nr_updates)) + bch2_btree_trans_peek_prev_updates(trans, iter, &k); + if (likely(k.k)) { if (iter->flags & BTREE_ITER_FILTER_SNAPSHOTS) { if (k.k->p.snapshot == iter->snapshot) |