summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_update_leaf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/btree_update_leaf.c')
-rw-r--r--libbcachefs/btree_update_leaf.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/libbcachefs/btree_update_leaf.c b/libbcachefs/btree_update_leaf.c
index c4054667..b9c777cc 100644
--- a/libbcachefs/btree_update_leaf.c
+++ b/libbcachefs/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);
}
@@ -560,7 +569,8 @@ static inline bool have_conflicting_read_lock(struct btree_trans *trans, struct
//if (path == pos)
// break;
- if (path->nodes_locked != path->nodes_intent_locked)
+ if (path->nodes_locked != path->nodes_intent_locked &&
+ !bch2_btree_path_upgrade(trans, path, path->level + 1))
return true;
}