summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-12-23 18:21:27 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2017-01-18 21:41:34 -0900
commit0fd192fcc98fadd65df6cc2f1b2922bb265a2069 (patch)
tree740b2f91c83b813f99983e8bf67a4161ce5479d4
parentda938135e15bcc078f26433403766fec145512df (diff)
bcache: avoid a deadlock when there's corrupt/duplicate journal entries
-rw-r--r--drivers/md/bcache/journal.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 4fd14101224a..1dcbaf251424 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -848,11 +848,19 @@ bsearch:
}
search_done:
- /* Find the journal bucket with the highest sequence number: */
+ /*
+ * Find the journal bucket with the highest sequence number:
+ *
+ * If there's duplicate journal entries in multiple buckets (which
+ * definitely isn't supposed to happen, but...) - make sure to start
+ * cur_idx at the last of those buckets, so we don't deadlock trying to
+ * allocate
+ */
seq = 0;
for (i = 0; i < nr_buckets; i++)
- if (ja->bucket_seq[i] > seq) {
+ if (ja->bucket_seq[i] >= seq &&
+ ja->bucket_seq[i] != ja->bucket_seq[(i + 1) % nr_buckets]) {
/*
* When journal_next_bucket() goes to allocate for
* the first time, it'll use the bucket after