return ret;
}
-static noinline struct bkey_i *__btree_trans_peek_updates(struct btree_iter *iter,
- struct bpos pos)
+static noinline struct bkey_i *__btree_trans_peek_updates(struct btree_iter *iter)
{
struct btree_insert_entry *i;
struct bkey_i *ret = NULL;
continue;
if (i->btree_id > iter->btree_id)
break;
- if (bpos_cmp(i->k->k.p, pos) < 0)
+ if (bpos_cmp(i->k->k.p, iter->real_pos) < 0)
continue;
if (!ret || bpos_cmp(i->k->k.p, ret->k.p) < 0)
ret = i->k;
return ret;
}
-static inline struct bkey_i *btree_trans_peek_updates(struct btree_iter *iter,
- struct bpos pos)
+static inline struct bkey_i *btree_trans_peek_updates(struct btree_iter *iter)
{
return iter->flags & BTREE_ITER_WITH_UPDATES
- ? __btree_trans_peek_updates(iter, pos)
+ ? __btree_trans_peek_updates(iter)
: NULL;
}
bch2_btree_iter_verify(iter);
bch2_btree_iter_verify_entry_exit(iter);
start:
- next_update = btree_trans_peek_updates(iter, search_key);
btree_iter_set_search_pos(iter, search_key);
while (1) {
if (unlikely(ret))
return bkey_s_c_err(ret);
+ /*
+ * btree_iter_level_peek() mutates iter->real_pos, which
+ * btree_trans_peek_updates() checks against, so we have to call
+ * them in this order:
+ */
+ next_update = btree_trans_peek_updates(iter);
k = btree_iter_level_peek(iter, &iter->l[0]);
-
if (next_update &&
bpos_cmp(next_update->k.p, iter->real_pos) <= 0) {
iter->k = next_update->k;
struct bkey_i *next_update;
struct bkey_cached *ck;
+ next_update = btree_trans_peek_updates(iter);
+
switch (btree_iter_type(iter)) {
case BTREE_ITER_KEYS:
k = btree_iter_level_peek_all(iter, &iter->l[0]);
BUG();
}
- next_update = btree_trans_peek_updates(iter, search_key);
if (next_update &&
(!k.k || bpos_cmp(next_update->k.p, k.k->p) <= 0)) {
iter->k = next_update->k;