diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-10 06:43:39 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-10 06:48:54 -0800 |
commit | 09a46b69f33b9aac32c422679a663c07a2585799 (patch) | |
tree | a57433aecb62de63eedc0f647c8c3ffe907c1ae6 | |
parent | f355b7a7f201be3edae8926a5c1baf5f2cfb6d33 (diff) |
bcache: hack around a race with journal reclaim
-rw-r--r-- | drivers/md/bcache/btree_update.c | 16 |
1 files changed, 15 insertions, 1 deletions
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); } |