summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_iter.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/btree_iter.c')
-rw-r--r--libbcachefs/btree_iter.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c
index ea0555b8..c365a2af 100644
--- a/libbcachefs/btree_iter.c
+++ b/libbcachefs/btree_iter.c
@@ -408,7 +408,7 @@ static void __bch2_btree_iter_verify(struct btree_iter *iter,
* For extents, the iterator may have skipped past deleted keys (but not
* whiteouts)
*/
- k = b->level || iter->flags & BTREE_ITER_IS_EXTENTS
+ k = b->level || btree_node_type_is_extents(iter->btree_id)
? bch2_btree_node_iter_prev_filter(&tmp, b, KEY_TYPE_discard)
: bch2_btree_node_iter_prev_all(&tmp, b);
if (k && bkey_iter_pos_cmp(b, k, &pos) >= 0) {
@@ -563,7 +563,7 @@ fixup_done:
if (!bch2_btree_node_iter_end(node_iter) &&
iter_current_key_modified &&
(b->level ||
- (iter->flags & BTREE_ITER_IS_EXTENTS))) {
+ btree_node_type_is_extents(iter->btree_id))) {
struct bset_tree *t;
struct bkey_packed *k, *k2, *p;
@@ -1271,6 +1271,29 @@ static unsigned btree_iter_pos_changed(struct btree_iter *iter, int cmp)
return l;
}
+void __bch2_btree_iter_set_pos(struct btree_iter *iter, struct bpos new_pos,
+ bool strictly_greater)
+{
+ struct bpos old = btree_iter_search_key(iter);
+ unsigned l;
+ int cmp;
+
+ iter->flags &= ~BTREE_ITER_IS_EXTENTS;
+ iter->flags |= strictly_greater ? BTREE_ITER_IS_EXTENTS : 0;
+ iter->pos = new_pos;
+
+ cmp = bkey_cmp(btree_iter_search_key(iter), old);
+ if (!cmp)
+ return;
+
+ l = btree_iter_pos_changed(iter, cmp);
+
+ if (l != iter->level)
+ btree_iter_set_dirty(iter, BTREE_ITER_NEED_TRAVERSE);
+ else
+ btree_iter_set_dirty(iter, BTREE_ITER_NEED_PEEK);
+}
+
void bch2_btree_iter_set_pos(struct btree_iter *iter, struct bpos new_pos)
{
int cmp = bkey_cmp(new_pos, iter->pos);
@@ -1709,8 +1732,7 @@ static inline void bch2_btree_iter_init(struct btree_trans *trans,
iter->nodes_locked = 0;
iter->nodes_intent_locked = 0;
for (i = 0; i < ARRAY_SIZE(iter->l); i++)
- iter->l[i].b = NULL;
- iter->l[iter->level].b = BTREE_ITER_NO_NODE_INIT;
+ iter->l[i].b = BTREE_ITER_NO_NODE_INIT;
prefetch(c->btree_roots[btree_id].b);
}
@@ -1729,7 +1751,12 @@ static inline void __bch2_trans_iter_free(struct btree_trans *trans,
int bch2_trans_iter_put(struct btree_trans *trans,
struct btree_iter *iter)
{
- int ret = btree_iter_err(iter);
+ int ret;
+
+ if (IS_ERR_OR_NULL(iter))
+ return 0;
+
+ ret = btree_iter_err(iter);
if (!(trans->iters_touched & (1ULL << iter->idx)) &&
!(iter->flags & BTREE_ITER_KEEP_UNTIL_COMMIT))
@@ -1742,6 +1769,9 @@ int bch2_trans_iter_put(struct btree_trans *trans,
int bch2_trans_iter_free(struct btree_trans *trans,
struct btree_iter *iter)
{
+ if (IS_ERR_OR_NULL(iter))
+ return 0;
+
trans->iters_touched &= ~(1ULL << iter->idx);
return bch2_trans_iter_put(trans, iter);
@@ -1939,7 +1969,8 @@ struct btree_iter *bch2_trans_get_iter(struct btree_trans *trans,
__btree_trans_get_iter(trans, btree_id, pos, flags);
if (!IS_ERR(iter))
- bch2_btree_iter_set_pos(iter, pos);
+ __bch2_btree_iter_set_pos(iter, pos,
+ btree_node_type_is_extents(btree_id));
return iter;
}
@@ -1981,8 +2012,8 @@ struct btree_iter *bch2_trans_copy_iter(struct btree_trans *trans,
trans->iters_live |= 1ULL << iter->idx;
/*
- * Don't mark it as touched, we don't need to preserve this iter since
- * it's cheap to copy it again:
+ * We don't need to preserve this iter since it's cheap to copy it
+ * again - this will cause trans_iter_put() to free it right away:
*/
trans->iters_touched &= ~(1ULL << iter->idx);