summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_cache.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-06-03 16:21:35 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2020-06-03 19:56:33 -0400
commit1952c0790c74e4e81d7066a19aabc5c55a13f10f (patch)
tree501fa5db6a5f1fd3b2412a2660e995c74ebf0bba /libbcachefs/btree_cache.c
parent90d54b388666b258c97be6a4e632824d136356c4 (diff)
Update bcachefs sources to c9b4a210f9 fixup! bcachefs: Fixes for going RO
Diffstat (limited to 'libbcachefs/btree_cache.c')
-rw-r--r--libbcachefs/btree_cache.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/libbcachefs/btree_cache.c b/libbcachefs/btree_cache.c
index c12f8a6..fc69f68 100644
--- a/libbcachefs/btree_cache.c
+++ b/libbcachefs/btree_cache.c
@@ -553,7 +553,6 @@ out_unlock:
list_del_init(&b->list);
mutex_unlock(&bc->lock);
- memalloc_nofs_restore(flags);
out:
b->flags = 0;
b->written = 0;
@@ -566,6 +565,7 @@ out:
bch2_time_stats_update(&c->times[BCH_TIME_btree_node_mem_alloc],
start_time);
+ memalloc_nofs_restore(flags);
return b;
err:
/* Try to cannibalize another cached btree node: */
@@ -581,6 +581,7 @@ err:
}
mutex_unlock(&bc->lock);
+ memalloc_nofs_restore(flags);
return ERR_PTR(-ENOMEM);
}
@@ -849,6 +850,18 @@ struct btree *bch2_btree_node_get_sibling(struct bch_fs *c,
if (!parent)
return NULL;
+ /*
+ * There's a corner case where a btree_iter might have a node locked
+ * that is just outside its current pos - when
+ * bch2_btree_iter_set_pos_same_leaf() gets to the end of the node.
+ *
+ * But the lock ordering checks in __bch2_btree_node_lock() go off of
+ * iter->pos, not the node's key: so if the iterator is marked as
+ * needing to be traversed, we risk deadlock if we don't bail out here:
+ */
+ if (iter->uptodate >= BTREE_ITER_NEED_TRAVERSE)
+ return ERR_PTR(-EINTR);
+
if (!bch2_btree_node_relock(iter, level + 1)) {
ret = ERR_PTR(-EINTR);
goto out;