bcachefs: Consolidate intent lock code in btree_path_up_until_good_node
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 8 Sep 2021 00:23:30 +0000 (20:23 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:12 +0000 (17:09 -0400)
We need to take all needed intent locks when relocking an iterator:
bch2_btree_path_traverse() had a special cased, faster version of this,
but it really should be in up_until_good_node() so that set_pos() can
use it too.

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

index d2ee6e9aa370124f83cd719167421dd72c81ca84..fbe1a1170df6f6c36669212e2850e91deb70a9c4 100644 (file)
@@ -1352,10 +1352,7 @@ static inline unsigned btree_path_up_until_good_node(struct btree_trans *trans,
                                                     struct btree_path *path,
                                                     int check_pos)
 {
-       unsigned l = path->level;
-
-       if (!path->nodes_locked)
-               btree_path_get_locks(trans, path, false, _THIS_IP_);
+       unsigned i, l = path->level;
 
        while (btree_path_node(path, l) &&
               !btree_path_good_node(trans, path, l, check_pos)) {
@@ -1364,6 +1361,17 @@ static inline unsigned btree_path_up_until_good_node(struct btree_trans *trans,
                l++;
        }
 
+       /* If we need intent locks, take them too: */
+       for (i = l + 1;
+            i < path->locks_want && btree_path_node(path, i);
+            i++)
+               if (!bch2_btree_node_relock(trans, path, i))
+                       while (l <= i) {
+                               btree_node_unlock(path, l);
+                               path->l[l].b = BTREE_ITER_NO_NODE_UP;
+                               l++;
+                       }
+
        return l;
 }
 
@@ -1381,7 +1389,7 @@ static int btree_path_traverse_one(struct btree_trans *trans,
                                   unsigned flags,
                                   unsigned long trace_ip)
 {
-       unsigned l, depth_want = path->level;
+       unsigned depth_want = path->level;
        int ret = 0;
 
        /*
@@ -1403,17 +1411,6 @@ static int btree_path_traverse_one(struct btree_trans *trans,
 
        path->level = btree_path_up_until_good_node(trans, path, 0);
 
-       /* If we need intent locks, take them too: */
-       for (l = path->level + 1;
-            l < path->locks_want && btree_path_node(path, l);
-            l++)
-               if (!bch2_btree_node_relock(trans, path, l))
-                       while (path->level <= l) {
-                               btree_node_unlock(path, path->level);
-                               path->l[path->level].b = BTREE_ITER_NO_NODE_UP;
-                               path->level++;
-                       }
-
        /*
         * Note: path->nodes[path->level] may be temporarily NULL here - that
         * would indicate to other code that we got to the end of the btree,