From 5288e66a7b732aae8a905ddba86b3b65acb6a911 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Fri, 4 Jun 2021 00:29:49 -0400 Subject: [PATCH] bcachefs: BTREE_ITER_WITH_UPDATES This drops bch2_btree_iter_peek_with_updates() and replaces it with a new flag, BTREE_ITER_WITH_UPDATES, and also reworks bch2_btree_iter_peek_slot() to respect it too. Signed-off-by: Kent Overstreet --- fs/bcachefs/btree_iter.c | 79 ++++++++++++++++----------------- fs/bcachefs/btree_iter.h | 3 -- fs/bcachefs/btree_types.h | 13 +++--- fs/bcachefs/btree_update_leaf.c | 12 ++--- 4 files changed, 50 insertions(+), 57 deletions(-) diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index eccc7a39df014..d6de24e92339b 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -864,10 +864,9 @@ static inline struct bkey_s_c __btree_iter_unpack(struct btree_iter *iter, /* peek_all() doesn't skip deleted keys */ static inline struct bkey_s_c btree_iter_level_peek_all(struct btree_iter *iter, - struct btree_iter_level *l, - struct bkey *u) + struct btree_iter_level *l) { - return __btree_iter_unpack(iter, l, u, + return __btree_iter_unpack(iter, l, &iter->k, bch2_btree_node_iter_peek_all(&l->iter, l->b)); } @@ -1651,23 +1650,39 @@ static inline bool btree_iter_set_pos_to_prev_leaf(struct btree_iter *iter) return ret; } -static struct bkey_i *btree_trans_peek_updates(struct btree_trans *trans, - enum btree_id btree_id, struct bpos pos) +static noinline struct bkey_i *__btree_trans_peek_updates(struct btree_iter *iter, + struct bpos pos) { struct btree_insert_entry *i; + struct bkey_i *ret = NULL; - trans_for_each_update2(trans, i) - if ((cmp_int(btree_id, i->iter->btree_id) ?: - bkey_cmp(pos, i->k->k.p)) <= 0) { - if (btree_id == i->iter->btree_id) - return i->k; + trans_for_each_update2(iter->trans, i) { + if (i->btree_id < iter->btree_id) + continue; + if (i->btree_id > iter->btree_id) break; - } + if (bpos_cmp(i->k->k.p, pos) < 0) + continue; + if (!ret || bpos_cmp(i->k->k.p, ret->k.p) < 0) + ret = i->k; + } - return NULL; + return ret; +} + +static inline struct bkey_i *btree_trans_peek_updates(struct btree_iter *iter, + struct bpos pos) +{ + return iter->flags & BTREE_ITER_WITH_UPDATES + ? __btree_trans_peek_updates(iter, pos) + : NULL; } -static inline struct bkey_s_c __btree_iter_peek(struct btree_iter *iter, bool with_updates) +/** + * bch2_btree_iter_peek: returns first key greater than or equal to iterator's + * current position + */ +struct bkey_s_c bch2_btree_iter_peek(struct btree_iter *iter) { struct bpos search_key = btree_iter_search_key(iter); struct bkey_i *next_update; @@ -1678,9 +1693,7 @@ static inline struct bkey_s_c __btree_iter_peek(struct btree_iter *iter, bool wi bch2_btree_iter_verify(iter); bch2_btree_iter_verify_entry_exit(iter); start: - next_update = with_updates - ? btree_trans_peek_updates(iter->trans, iter->btree_id, search_key) - : NULL; + next_update = btree_trans_peek_updates(iter, search_key); btree_iter_set_search_pos(iter, search_key); while (1) { @@ -1691,8 +1704,10 @@ start: k = btree_iter_level_peek(iter, &iter->l[0]); if (next_update && - bpos_cmp(next_update->k.p, iter->real_pos) <= 0) + bpos_cmp(next_update->k.p, iter->real_pos) <= 0) { + iter->k = next_update->k; k = bkey_i_to_s_c(next_update); + } if (likely(k.k)) { if (bkey_deleted(k.k)) { @@ -1722,15 +1737,6 @@ start: return k; } -/** - * bch2_btree_iter_peek: returns first key greater than or equal to iterator's - * current position - */ -struct bkey_s_c bch2_btree_iter_peek(struct btree_iter *iter) -{ - return __btree_iter_peek(iter, false); -} - /** * bch2_btree_iter_next: returns first key greater than iterator's current * position @@ -1743,19 +1749,6 @@ struct bkey_s_c bch2_btree_iter_next(struct btree_iter *iter) return bch2_btree_iter_peek(iter); } -struct bkey_s_c bch2_btree_iter_peek_with_updates(struct btree_iter *iter) -{ - return __btree_iter_peek(iter, true); -} - -struct bkey_s_c bch2_btree_iter_next_with_updates(struct btree_iter *iter) -{ - if (!bch2_btree_iter_advance(iter)) - return bkey_s_c_null; - - return bch2_btree_iter_peek_with_updates(iter); -} - /** * bch2_btree_iter_peek_prev: returns first key less than or equal to * iterator's current position @@ -1767,6 +1760,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter) int ret; EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS); + EBUG_ON(iter->flags & BTREE_ITER_WITH_UPDATES); bch2_btree_iter_verify(iter); bch2_btree_iter_verify_entry_exit(iter); @@ -1890,7 +1884,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) if (unlikely(ret)) return bkey_s_c_err(ret); - k = btree_iter_level_peek_all(iter, l, &iter->k); + k = btree_iter_level_peek_all(iter, l); EBUG_ON(k.k && bkey_deleted(k.k) && bkey_cmp(k.k->p, iter->pos) == 0); @@ -1926,12 +1920,17 @@ struct bkey_s_c bch2_btree_iter_prev_slot(struct btree_iter *iter) struct bkey_s_c bch2_btree_iter_peek_cached(struct btree_iter *iter) { + struct bkey_i *next_update; struct bkey_cached *ck; int ret; EBUG_ON(btree_iter_type(iter) != BTREE_ITER_CACHED); bch2_btree_iter_verify(iter); + next_update = btree_trans_peek_updates(iter, iter->pos); + if (next_update && !bpos_cmp(next_update->k.p, iter->pos)) + return bkey_i_to_s_c(next_update); + ret = btree_iter_traverse(iter); if (unlikely(ret)) return bkey_s_c_err(ret); diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h index 18732ca531ec3..ba98cfea4d608 100644 --- a/fs/bcachefs/btree_iter.h +++ b/fs/bcachefs/btree_iter.h @@ -153,9 +153,6 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *); struct bkey_s_c bch2_btree_iter_peek(struct btree_iter *); struct bkey_s_c bch2_btree_iter_next(struct btree_iter *); -struct bkey_s_c bch2_btree_iter_peek_with_updates(struct btree_iter *); -struct bkey_s_c bch2_btree_iter_next_with_updates(struct btree_iter *); - struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *); struct bkey_s_c bch2_btree_iter_prev(struct btree_iter *); diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index 97e0216486856..89780b4aa0575 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -209,12 +209,13 @@ enum btree_iter_type { * @pos or the first key strictly greater than @pos */ #define BTREE_ITER_IS_EXTENTS (1 << 6) -#define BTREE_ITER_ERROR (1 << 7) -#define BTREE_ITER_SET_POS_AFTER_COMMIT (1 << 8) -#define BTREE_ITER_CACHED_NOFILL (1 << 9) -#define BTREE_ITER_CACHED_NOCREATE (1 << 10) -#define BTREE_ITER_NOT_EXTENTS (1 << 11) -#define BTREE_ITER_ALL_SNAPSHOTS (1 << 12) +#define BTREE_ITER_NOT_EXTENTS (1 << 7) +#define BTREE_ITER_ERROR (1 << 8) +#define BTREE_ITER_SET_POS_AFTER_COMMIT (1 << 9) +#define BTREE_ITER_CACHED_NOFILL (1 << 10) +#define BTREE_ITER_CACHED_NOCREATE (1 << 11) +#define BTREE_ITER_WITH_UPDATES (1 << 12) +#define BTREE_ITER_ALL_SNAPSHOTS (1 << 13) enum btree_iter_uptodate { BTREE_ITER_UPTODATE = 0, diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index 9eb31d31ed42a..123127980853f 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -841,13 +841,11 @@ static int extent_handle_overwrites(struct btree_trans *trans, struct bpos start = bkey_start_pos(&insert->k); struct bkey_i *update; struct bkey_s_c k; - int ret = 0; - - iter = bch2_trans_get_iter(trans, btree_id, start, - BTREE_ITER_INTENT); - k = bch2_btree_iter_peek_with_updates(iter); + int ret; - while (k.k && !(ret = bkey_err(k))) { + for_each_btree_key(trans, iter, btree_id, start, + BTREE_ITER_INTENT| + BTREE_ITER_WITH_UPDATES, k, ret) { if (bkey_cmp(insert->k.p, bkey_start_pos(k.k)) <= 0) break; @@ -898,8 +896,6 @@ static int extent_handle_overwrites(struct btree_trans *trans, bch2_trans_iter_put(trans, update_iter); break; } - - k = bch2_btree_iter_next_with_updates(iter); } bch2_trans_iter_put(trans, iter); -- 2.30.2