From 09a46b69f33b9aac32c422679a663c07a2585799 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Mon, 10 Oct 2016 06:43:39 -0800 Subject: bcache: hack around a race with journal reclaim --- drivers/md/bcache/btree_update.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c index a8df0fab3e5f..ae3f97bc3fa0 100644 --- a/drivers/md/bcache/btree_update.c +++ b/drivers/md/bcache/btree_update.c @@ -695,7 +695,21 @@ static void btree_node_flush(struct journal *j, struct journal_entry_pin *pin) struct btree *b = container_of(w, struct btree, writes[w->index]); six_lock_read(&b->lock); - __bch_btree_node_write(b, NULL, w->index); + /* + * Reusing a btree node can race with the journal reclaim code calling + * the journal pin flush fn, and there's no good fix for this: we don't + * really want journal_pin_drop() to block until the flush fn is no + * longer running, because journal_pin_drop() is called from the btree + * node write endio function, and we can't wait on the flush fn to + * finish running in mca_reap() - where we make reused btree nodes ready + * to use again - because there, we're holding the lock this function + * needs - deadlock. + * + * So, the b->level check is a hack so we don't try to write nodes we + * shouldn't: + */ + if (!b->level) + __bch_btree_node_write(b, NULL, w->index); six_unlock_read(&b->lock); } -- cgit v1.2.3