diff options
Diffstat (limited to 'libbcachefs/btree_iter.c')
-rw-r--r-- | libbcachefs/btree_iter.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c index 93194e6..cdec05c 100644 --- a/libbcachefs/btree_iter.c +++ b/libbcachefs/btree_iter.c @@ -2013,6 +2013,13 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, unsigned flags) { struct btree_iter *iter, *best = NULL; + struct bpos real_pos, pos_min = POS_MIN; + + if ((flags & BTREE_ITER_TYPE) != BTREE_ITER_NODES && + btree_node_type_is_extents(btree_id) && + !(flags & BTREE_ITER_NOT_EXTENTS) && + !(flags & BTREE_ITER_ALL_SNAPSHOTS)) + flags |= BTREE_ITER_IS_EXTENTS; if ((flags & BTREE_ITER_TYPE) != BTREE_ITER_NODES && !btree_type_has_snapshots(btree_id)) @@ -2022,6 +2029,12 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, pos.snapshot = btree_type_has_snapshots(btree_id) ? U32_MAX : 0; + real_pos = pos; + + if ((flags & BTREE_ITER_IS_EXTENTS) && + bkey_cmp(pos, POS_MAX)) + real_pos = bpos_nosnap_successor(pos); + trans_for_each_iter(trans, iter) { if (btree_iter_type(iter) != (flags & BTREE_ITER_TYPE)) continue; @@ -2030,8 +2043,8 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, continue; if (best) { - int cmp = bkey_cmp(bpos_diff(best->real_pos, pos), - bpos_diff(iter->real_pos, pos)); + int cmp = bkey_cmp(bpos_diff(best->real_pos, real_pos), + bpos_diff(iter->real_pos, real_pos)); if (cmp < 0 || ((cmp == 0 && btree_iter_keep(trans, iter)))) @@ -2041,6 +2054,13 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, best = iter; } + trace_trans_get_iter(_RET_IP_, trans->ip, + btree_id, + &real_pos, locks_want, + best ? &best->real_pos : &pos_min, + best ? best->locks_want : 0, + best ? best->uptodate : BTREE_ITER_NEED_TRAVERSE); + if (!best) { iter = btree_trans_iter_alloc(trans); bch2_btree_iter_init(trans, iter, btree_id); @@ -2054,12 +2074,6 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, trans->iters_live |= 1ULL << iter->idx; trans->iters_touched |= 1ULL << iter->idx; - if ((flags & BTREE_ITER_TYPE) != BTREE_ITER_NODES && - btree_node_type_is_extents(btree_id) && - !(flags & BTREE_ITER_NOT_EXTENTS) && - !(flags & BTREE_ITER_ALL_SNAPSHOTS)) - flags |= BTREE_ITER_IS_EXTENTS; - iter->flags = flags; iter->snapshot = pos.snapshot; @@ -2078,19 +2092,20 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, btree_iter_get_locks(iter, true, false); } - while (iter->level < depth) { + while (iter->level != depth) { btree_node_unlock(iter, iter->level); iter->l[iter->level].b = BTREE_ITER_NO_NODE_INIT; - iter->level++; + iter->uptodate = BTREE_ITER_NEED_TRAVERSE; + if (iter->level < depth) + iter->level++; + else + iter->level--; } - while (iter->level > depth) - iter->l[--iter->level].b = BTREE_ITER_NO_NODE_INIT; - iter->min_depth = depth; bch2_btree_iter_set_pos(iter, pos); - btree_iter_set_search_pos(iter, btree_iter_search_key(iter)); + btree_iter_set_search_pos(iter, real_pos); return iter; } |