summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-11-03 12:08:02 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2021-11-04 12:25:23 -0400
commite5a343c27a75f77b91d79dedcca449b321a7c8f6 (patch)
treea87c9a08cf5909530ae841a7c5c603424381eae8
parent47db6876ac870bdbacbccc4795e8de0290b75ef9 (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 8c7fc74f1a77..f5d8a7306008 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -175,8 +175,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 61bbb7bc54b3..2dc588283252 100644
--- a/fs/bcachefs/btree_iter.h
+++ b/fs/bcachefs/btree_iter.h
@@ -166,6 +166,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 c405466733e2..5cddb572a55a 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);
}