]> www.infradead.org Git - users/willy/xarray.git/commitdiff
bcachefs: btree_iter->should_be_locked
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 4 Jun 2021 21:17:45 +0000 (17:17 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:05 +0000 (17:09 -0400)
Add a field to struct btree_iter for tracking whether it should be
locked - this fixes spurious transaction restarts in
bch2_trans_relock().

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_types.h

index 78eae21693470116c9f015ba8e8b21d9a307b23e..7246519b325023fee7a11a56998a14458496b951 100644 (file)
@@ -463,12 +463,20 @@ void bch2_trans_downgrade(struct btree_trans *trans)
 
 /* 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;
@@ -1427,9 +1435,16 @@ btree_iter_traverse(struct btree_iter *iter)
 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) */
@@ -1455,6 +1470,7 @@ struct btree *bch2_btree_iter_peek_node(struct btree_iter *iter)
        iter->pos = iter->real_pos = b->key.k.p;
 
        bch2_btree_iter_verify(iter);
+       iter->should_be_locked = true;
 
        return b;
 }
@@ -1511,6 +1527,7 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
        iter->pos = iter->real_pos = b->key.k.p;
 
        bch2_btree_iter_verify(iter);
+       iter->should_be_locked = true;
 
        return b;
 }
@@ -1527,6 +1544,7 @@ static void btree_iter_set_search_pos(struct btree_iter *iter, struct bpos new_p
                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);
@@ -1686,6 +1704,7 @@ start:
 
        bch2_btree_iter_verify_entry_exit(iter);
        bch2_btree_iter_verify(iter);
+       iter->should_be_locked = true;
        return k;
 }
 
@@ -1770,6 +1789,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
 out:
        bch2_btree_iter_verify_entry_exit(iter);
        bch2_btree_iter_verify(iter);
+       iter->should_be_locked = true;
        return k;
 no_key:
        /*
@@ -1869,6 +1889,8 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
 
        bch2_btree_iter_verify_entry_exit(iter);
        bch2_btree_iter_verify(iter);
+       iter->should_be_locked = true;
+
        return k;
 }
 
@@ -1906,6 +1928,8 @@ struct bkey_s_c bch2_btree_iter_peek_cached(struct btree_iter *iter)
                bkey_cmp(iter->pos, ck->key.pos));
        BUG_ON(!ck->valid);
 
+       iter->should_be_locked = true;
+
        return bkey_i_to_s_c(ck->k);
 }
 
index 01b834bf79f7e6ebc5359cea9f6d357f8d58b6ce..a2ce711fd61f0b981df5c940cfb3eb0c01420c7e 100644 (file)
@@ -178,6 +178,7 @@ static inline void bch2_btree_iter_set_pos(struct btree_iter *iter, struct bpos
        iter->k.p.offset        = iter->pos.offset      = new_pos.offset;
        iter->k.p.snapshot      = iter->pos.snapshot    = new_pos.snapshot;
        iter->k.size = 0;
+       iter->should_be_locked = false;
 }
 
 /* Sort order for locking btree iterators: */
index 50595f5f158bb465be30b29de70b483eb0506125..bb0f92e3b3abd8ed85e335fc3bb181304d0011f1 100644 (file)
@@ -252,7 +252,13 @@ struct btree_iter {
        u8                      idx;
 
        enum btree_id           btree_id:4;
-       enum btree_iter_uptodate uptodate:4;
+       enum btree_iter_uptodate uptodate:3;
+       /*
+        * True if we've returned a key (and thus are expected to keep it
+        * locked), false after set_pos - for avoiding spurious transaction
+        * restarts in bch2_trans_relock():
+        */
+       bool                    should_be_locked:1;
        unsigned                level:4,
                                min_depth:4,
                                locks_want:4,