summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_iter.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/btree_iter.c')
-rw-r--r--libbcachefs/btree_iter.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c
index 0b505a73..ee463f36 100644
--- a/libbcachefs/btree_iter.c
+++ b/libbcachefs/btree_iter.c
@@ -202,21 +202,20 @@ bool __bch2_btree_node_lock(struct btree *b, struct bpos pos,
/* Btree iterator locking: */
-
static void btree_iter_drop_extra_locks(struct btree_iter *iter)
{
unsigned l;
while (iter->nodes_locked &&
(l = __fls(iter->nodes_locked)) > iter->locks_want) {
- if (!btree_node_locked(iter, l))
- panic("l %u nodes_locked %u\n", l, iter->nodes_locked);
-
if (l > iter->level) {
btree_node_unlock(iter, l);
- } else if (btree_node_intent_locked(iter, l)) {
- six_lock_downgrade(&iter->nodes[l]->lock);
- iter->nodes_intent_locked ^= 1 << l;
+ } else {
+ if (btree_node_intent_locked(iter, l)) {
+ six_lock_downgrade(&iter->nodes[l]->lock);
+ iter->nodes_intent_locked ^= 1 << l;
+ }
+ break;
}
}
}
@@ -861,7 +860,8 @@ int __must_check __bch2_btree_iter_traverse(struct btree_iter *iter)
i < iter->locks_want && iter->nodes[i];
i++)
if (!bch2_btree_node_relock(iter, i)) {
- while (iter->nodes[iter->level] &&
+ while (iter->level < BTREE_MAX_DEPTH &&
+ iter->nodes[iter->level] &&
iter->level + 1 < iter->locks_want)
btree_iter_up(iter);
break;
@@ -872,7 +872,8 @@ int __must_check __bch2_btree_iter_traverse(struct btree_iter *iter)
* If the current node isn't locked, go up until we have a locked node
* or run out of nodes:
*/
- while (iter->nodes[iter->level] &&
+ while (iter->level < BTREE_MAX_DEPTH &&
+ iter->nodes[iter->level] &&
!(is_btree_node(iter, iter->level) &&
bch2_btree_node_relock(iter, iter->level) &&
btree_iter_pos_cmp(iter->pos,
@@ -884,7 +885,8 @@ int __must_check __bch2_btree_iter_traverse(struct btree_iter *iter)
* If we've got a btree node locked (i.e. we aren't about to relock the
* root) - advance its node iterator if necessary:
*/
- if (iter->nodes[iter->level]) {
+ if (iter->level < BTREE_MAX_DEPTH &&
+ iter->nodes[iter->level]) {
struct bkey_s_c k;
while ((k = __btree_iter_peek_all(iter)).k &&
@@ -956,7 +958,8 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter, unsigned depth)
btree_iter_up(iter);
- if (!iter->nodes[iter->level])
+ if (iter->level == BTREE_MAX_DEPTH ||
+ !iter->nodes[iter->level])
return NULL;
/* parent node usually won't be locked: redo traversal if necessary */