/* Btree transaction locking: */
+static inline bool btree_iter_should_be_locked(struct btree_trans *trans,
+ struct btree_iter *iter)
+{
+ return (iter->flags & BTREE_ITER_KEEP_UNTIL_COMMIT) ||
+ iter->should_be_locked;
+}
+
bool bch2_trans_relock(struct btree_trans *trans)
{
struct btree_iter *iter;
trans_for_each_iter(trans, iter)
- if (!bch2_btree_iter_relock(iter, _RET_IP_)) {
+ if (!bch2_btree_iter_relock(iter, _RET_IP_) &&
+ btree_iter_should_be_locked(trans, iter)) {
trace_trans_restart_relock(trans->ip, _RET_IP_,
iter->btree_id, &iter->real_pos);
return false;
int __must_check
bch2_btree_iter_traverse(struct btree_iter *iter)
{
+ int ret;
+
btree_iter_set_search_pos(iter, btree_iter_search_key(iter));
- return btree_iter_traverse(iter);
+ ret = btree_iter_traverse(iter);
+ if (ret)
+ return ret;
+
+ iter->should_be_locked = true;
+ return 0;
}
/* Iterate across nodes (leaf and interior nodes) */
iter->pos = iter->real_pos = b->key.k.p;
bch2_btree_iter_verify(iter);
+ iter->should_be_locked = true;
return b;
}
iter->pos = iter->real_pos = b->key.k.p;
bch2_btree_iter_verify(iter);
+ iter->should_be_locked = true;
return b;
}
goto out;
iter->real_pos = new_pos;
+ iter->should_be_locked = false;
if (unlikely(btree_iter_type(iter) == BTREE_ITER_CACHED)) {
btree_node_unlock(iter, 0);
bch2_btree_iter_verify_entry_exit(iter);
bch2_btree_iter_verify(iter);
+ iter->should_be_locked = true;
return k;
}
out:
bch2_btree_iter_verify_entry_exit(iter);
bch2_btree_iter_verify(iter);
+ iter->should_be_locked = true;
return k;
no_key:
/*
bch2_btree_iter_verify_entry_exit(iter);
bch2_btree_iter_verify(iter);
+ iter->should_be_locked = true;
+
return k;
}
bkey_cmp(iter->pos, ck->key.pos));
BUG_ON(!ck->valid);
+ iter->should_be_locked = true;
+
return bkey_i_to_s_c(ck->k);
}