]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: Delay setting path->should_be_locked
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 11 Mar 2022 04:22:49 +0000 (23:22 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:27 +0000 (17:09 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_iter.c

index 1cfd2e9015b100fb4c607b85c99c92b2e6afe826..b18e4fcc46e55ccb51c3d5e7621260a723823994 100644 (file)
@@ -427,8 +427,8 @@ bool bch2_btree_path_relock_intent(struct btree_trans *trans,
        return true;
 }
 
-__flatten
-static bool bch2_btree_path_relock(struct btree_trans *trans,
+noinline __flatten
+static bool __bch2_btree_path_relock(struct btree_trans *trans,
                        struct btree_path *path, unsigned long trace_ip)
 {
        bool ret = btree_path_get_locks(trans, path, false);
@@ -441,6 +441,14 @@ static bool bch2_btree_path_relock(struct btree_trans *trans,
        return ret;
 }
 
+static inline bool bch2_btree_path_relock(struct btree_trans *trans,
+                       struct btree_path *path, unsigned long trace_ip)
+{
+       return btree_node_locked(path, path->level)
+               ? true
+               : __bch2_btree_path_relock(trans, path, trace_ip);
+}
+
 bool __bch2_btree_path_upgrade(struct btree_trans *trans,
                               struct btree_path *path,
                               unsigned new_locks_want)
@@ -2388,9 +2396,6 @@ struct bkey_s_c bch2_btree_iter_peek(struct btree_iter *iter)
                        iter->update_path = bch2_btree_path_set_pos(trans,
                                                iter->update_path, pos,
                                                iter->flags & BTREE_ITER_INTENT);
-
-                       BUG_ON(!(iter->update_path->nodes_locked & 1));
-                       iter->update_path->should_be_locked = true;
                }
 
                /*
@@ -2428,8 +2433,12 @@ struct bkey_s_c bch2_btree_iter_peek(struct btree_iter *iter)
        BUG_ON(!iter->path->nodes_locked);
 out:
        if (iter->update_path) {
-               BUG_ON(!(iter->update_path->nodes_locked & 1));
-               iter->update_path->should_be_locked = true;
+               if (unlikely(!bch2_btree_path_relock(trans, iter->update_path, _THIS_IP_))) {
+                       k = bkey_s_c_err(-EINTR);
+               } else {
+                       BUG_ON(!(iter->update_path->nodes_locked & 1));
+                       iter->update_path->should_be_locked = true;
+               }
        }
        iter->path->should_be_locked = true;