diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-06-04 00:29:49 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2021-06-10 13:22:54 -0400 |
commit | 22dff78704b9e9e2c8539c4c0dc1a861241e8f26 (patch) | |
tree | 927231f851f1816b2ccf8c05e3d080635c34a1c3 | |
parent | f2309daa61179e07b02ba9dad80986cce376bc33 (diff) |
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 <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/btree_iter.c | 177 | ||||
-rw-r--r-- | fs/bcachefs/btree_iter.h | 3 | ||||
-rw-r--r-- | fs/bcachefs/btree_types.h | 13 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 12 |
4 files changed, 99 insertions, 106 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index 9c19b5fd5a83..830a6de02110 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -857,10 +857,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)); } @@ -1644,15 +1643,18 @@ 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 inline struct bkey_i *btree_trans_peek_updates(struct btree_iter *iter, + struct bpos pos) { struct btree_insert_entry *i; - 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) + if (!(iter->flags & BTREE_ITER_WITH_UPDATES)) + return NULL; + + trans_for_each_update2(iter->trans, i) + if ((cmp_int(iter->btree_id, i->iter->btree_id) ?: + bkey_cmp(pos, i->k->k.p)) <= 0) { + if (iter->btree_id == i->iter->btree_id) return i->k; break; } @@ -1660,7 +1662,11 @@ static struct bkey_i *btree_trans_peek_updates(struct btree_trans *trans, return 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; @@ -1671,9 +1677,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) { @@ -1716,15 +1720,6 @@ start: } /** - * 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 */ @@ -1736,19 +1731,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 @@ -1760,6 +1742,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); @@ -1821,52 +1804,9 @@ struct bkey_s_c bch2_btree_iter_prev(struct btree_iter *iter) return bch2_btree_iter_peek_prev(iter); } -static inline struct bkey_s_c -__bch2_btree_iter_peek_slot_extents(struct btree_iter *iter) -{ - struct bkey_s_c k; - struct bpos pos, next_start; - - /* keys & holes can't span inode numbers: */ - if (iter->pos.offset == KEY_OFFSET_MAX) { - if (iter->pos.inode == KEY_INODE_MAX) - return bkey_s_c_null; - - bch2_btree_iter_set_pos(iter, bkey_successor(iter, iter->pos)); - } - - pos = iter->pos; - k = bch2_btree_iter_peek(iter); - iter->pos = pos; - - if (bkey_err(k)) - return k; - - if (k.k && bkey_cmp(bkey_start_pos(k.k), iter->pos) <= 0) - return k; - - next_start = k.k ? bkey_start_pos(k.k) : POS_MAX; - - bkey_init(&iter->k); - iter->k.p = iter->pos; - bch2_key_resize(&iter->k, - min_t(u64, KEY_SIZE_MAX, - (next_start.inode == iter->pos.inode - ? next_start.offset - : KEY_OFFSET_MAX) - - iter->pos.offset)); - - EBUG_ON(!iter->k.size); - - bch2_btree_iter_verify_entry_exit(iter); - bch2_btree_iter_verify(iter); - - return (struct bkey_s_c) { &iter->k, NULL }; -} - struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) { - struct btree_iter_level *l = &iter->l[0]; + struct bpos search_key = btree_iter_search_key(iter); struct bkey_s_c k; int ret; @@ -1874,24 +1814,78 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) bch2_btree_iter_verify(iter); bch2_btree_iter_verify_entry_exit(iter); - btree_iter_set_search_pos(iter, btree_iter_search_key(iter)); + btree_iter_set_search_pos(iter, search_key); - if (iter->flags & BTREE_ITER_IS_EXTENTS) - return __bch2_btree_iter_peek_slot_extents(iter); + /* extents can't span inode numbers: */ + if ((iter->flags & BTREE_ITER_IS_EXTENTS) && + iter->pos.offset == KEY_OFFSET_MAX) { + if (iter->pos.inode == KEY_INODE_MAX) + return bkey_s_c_null; + + bch2_btree_iter_set_pos(iter, bpos_nosnap_successor(iter->pos)); + } ret = btree_iter_traverse(iter); if (unlikely(ret)) return bkey_s_c_err(ret); - k = btree_iter_level_peek_all(iter, l, &iter->k); + if (!(iter->flags & BTREE_ITER_IS_EXTENTS)) { + struct bkey_i *next_update = btree_trans_peek_updates(iter, search_key); - EBUG_ON(k.k && bkey_deleted(k.k) && bkey_cmp(k.k->p, iter->pos) == 0); + k = btree_iter_level_peek_all(iter, &iter->l[0]); + EBUG_ON(k.k && bkey_deleted(k.k) && bkey_cmp(k.k->p, iter->pos) == 0); - if (!k.k || bkey_cmp(iter->pos, k.k->p)) { - /* hole */ - bkey_init(&iter->k); - iter->k.p = iter->pos; - k = (struct bkey_s_c) { &iter->k, NULL }; + if (next_update && + (!k.k || bpos_cmp(next_update->k.p, k.k->p) <= 0)) { + iter->k = next_update->k; + k = bkey_i_to_s_c(next_update); + } + } else { + if ((iter->flags & BTREE_ITER_INTENT)) { + struct btree_iter *child = + btree_iter_child_alloc(iter, _THIS_IP_); + + btree_iter_copy(child, iter); + k = bch2_btree_iter_peek(child); + + if (k.k && !bkey_err(k)) + iter->k = child->k; + } else { + struct bpos pos = iter->pos; + + k = bch2_btree_iter_peek(iter); + iter->pos = pos; + } + + if (unlikely(bkey_err(k))) + return k; + } + + if (!(iter->flags & BTREE_ITER_IS_EXTENTS)) { + if (!k.k || + ((iter->flags & BTREE_ITER_ALL_SNAPSHOTS) + ? bpos_cmp(iter->pos, k.k->p) + : bkey_cmp(iter->pos, k.k->p))) { + bkey_init(&iter->k); + iter->k.p = iter->pos; + k = (struct bkey_s_c) { &iter->k, NULL }; + } + } else { + struct bpos next = k.k ? bkey_start_pos(k.k) : POS_MAX; + + if (bkey_cmp(iter->pos, next) < 0) { + bkey_init(&iter->k); + iter->k.p = iter->pos; + bch2_key_resize(&iter->k, + min_t(u64, KEY_SIZE_MAX, + (next.inode == iter->pos.inode + ? next.offset + : KEY_OFFSET_MAX) - + iter->pos.offset)); + + k = (struct bkey_s_c) { &iter->k, NULL }; + EBUG_ON(!k.k->size); + } } bch2_btree_iter_verify_entry_exit(iter); @@ -1919,12 +1913,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 18732ca531ec..ba98cfea4d60 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 36fa89bc9d34..ee392cdf58ad 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 0d566be7455e..6557dbc0b64e 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); |