bcachefs: Fix upgrade_readers()
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 3 Nov 2021 16:08:02 +0000 (12:08 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:15 +0000 (17:09 -0400)
The bch2_btree_path_upgrade() call was failing and tripping an assert -
path->level + 1 is in this case not necessarily exactly what we want,
fix it by upgrading exactly the locks we want.

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

index 806663799a087cfc5bce428f7f53b93e5731386e..2c28e65fdeb52735a602a15e21fa1759648aba17 100644 (file)
@@ -180,8 +180,8 @@ bool __bch2_btree_node_relock(struct btree_trans *trans,
        }
 }
 
-static bool bch2_btree_node_upgrade(struct btree_trans *trans,
-                                   struct btree_path *path, unsigned level)
+bool bch2_btree_node_upgrade(struct btree_trans *trans,
+                            struct btree_path *path, unsigned level)
 {
        struct btree *b = path->l[level].b;
 
index 16fa0fe1c5b710328d354287824fb42e36151dbd..64a3969db26330d06096911a3ad5ff61716869c7 100644 (file)
@@ -192,6 +192,9 @@ static inline int btree_trans_restart(struct btree_trans *trans)
        return -EINTR;
 }
 
+bool bch2_btree_node_upgrade(struct btree_trans *,
+                            struct btree_path *, unsigned);
+
 bool __bch2_btree_path_upgrade(struct btree_trans *,
                               struct btree_path *, unsigned);
 
index 8b4933add01783fef83bd75131a6913fb36f34e0..43ae2d83cfa7faacfcf16ae292fa3689ca4db933 100644 (file)
@@ -507,6 +507,15 @@ err:
        return ret;
 }
 
+static inline void path_upgrade_readers(struct btree_trans *trans, struct btree_path *path)
+{
+       unsigned l;
+
+       for (l = 0; l < BTREE_MAX_DEPTH; l++)
+               if (btree_node_read_locked(path, l))
+                       BUG_ON(!bch2_btree_node_upgrade(trans, path, l));
+}
+
 static inline void upgrade_readers(struct btree_trans *trans, struct btree_path *path)
 {
        struct btree *b = path_l(path)->b;
@@ -514,7 +523,7 @@ static inline void upgrade_readers(struct btree_trans *trans, struct btree_path
        do {
                if (path->nodes_locked &&
                    path->nodes_locked != path->nodes_intent_locked)
-                       BUG_ON(!bch2_btree_path_upgrade(trans, path, path->level + 1));
+                       path_upgrade_readers(trans, path);
        } while ((path = prev_btree_path(trans, path)) &&
                 path_l(path)->b == b);
 }