bcachefs: bch2_btree_path_upgrade() checks nodes_locked, not uptodate
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 11 Apr 2024 02:19:40 +0000 (22:19 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:19 +0000 (17:29 -0400)
In the key cache fill path, we use path_upgrade() on a path that isn't
uptodate yet but should be locked.

This change makes bch2_btree_path_upgrade() slightly looser so we can
use it in key cache upgrade, instead of the __ version.

Also, make the related assert - that path->uptodate implies nodes_locked
- slightly clearer.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_locking.c
fs/bcachefs/btree_locking.h

index e6adb2df3a571f2c216729f984fcc6bd00be4a0c..9a3ab56f6cfcb7ad6b581417989fc2756382dd1c 100644 (file)
@@ -840,20 +840,19 @@ int __bch2_trans_mutex_lock(struct btree_trans *trans,
 
 void bch2_btree_path_verify_locks(struct btree_path *path)
 {
-       unsigned l;
-
        /*
         * A path may be uptodate and yet have nothing locked if and only if
         * there is no node at path->level, which generally means we were
         * iterating over all nodes and got to the end of the btree
         */
-       if (!path->nodes_locked) {
-               BUG_ON(path->uptodate == BTREE_ITER_UPTODATE &&
-                      btree_path_node(path, path->level));
+       BUG_ON(path->uptodate == BTREE_ITER_UPTODATE &&
+              btree_path_node(path, path->level) &&
+              !path->nodes_locked);
+
+       if (!path->nodes_locked)
                return;
-       }
 
-       for (l = 0; l < BTREE_MAX_DEPTH; l++) {
+       for (unsigned l = 0; l < BTREE_MAX_DEPTH; l++) {
                int want = btree_lock_want(path, l);
                int have = btree_node_locked_type(path, l);
 
index 4bd72c855da1a4028106b70e10727ad07d578614..7f41545b9147f858c6459bdbcf3c78abbf2ebce3 100644 (file)
@@ -364,14 +364,14 @@ static inline int bch2_btree_path_upgrade(struct btree_trans *trans,
                                          struct btree_path *path,
                                          unsigned new_locks_want)
 {
-       struct get_locks_fail f;
+       struct get_locks_fail f = {};
        unsigned old_locks_want = path->locks_want;
 
        new_locks_want = min(new_locks_want, BTREE_MAX_DEPTH);
 
        if (path->locks_want < new_locks_want
            ? __bch2_btree_path_upgrade(trans, path, new_locks_want, &f)
-           : path->uptodate == BTREE_ITER_UPTODATE)
+           : path->nodes_locked)
                return 0;
 
        trace_and_count(trans->c, trans_restart_upgrade, trans, _THIS_IP_, path,