aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-11-03 12:08:02 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:15 -0400
commitf527afea5a2f3c2645080584dafeb6cc5314b652 (patch)
treee3efcef9f65c35e6016631e08327bc29678fd9d1
parentd7407292723ea79028afe6729432602ced243972 (diff)
bcachefs: Fix upgrade_readers()
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>
-rw-r--r--fs/bcachefs/btree_iter.c4
-rw-r--r--fs/bcachefs/btree_iter.h3
-rw-r--r--fs/bcachefs/btree_update_leaf.c11
3 files changed, 15 insertions, 3 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 806663799a08..2c28e65fdeb5 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -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;
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
index 16fa0fe1c5b7..64a3969db263 100644
--- a/fs/bcachefs/btree_iter.h
+++ b/fs/bcachefs/btree_iter.h
@@ -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);
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index 8b4933add017..43ae2d83cfa7 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -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);
}