summary refs log tree commit diff
path: root/drivers/md
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-07-11 22:42:14 -0700
committerKent Overstreet <kmo@daterainc.com>2013-07-12 00:22:48 -0700
commitfaa5673617656ee58369a3cfe4a312cfcdc59c81 (patch)
tree856e124ab4abab846bea0cdca7e41581eddf061f /drivers/md
parent5caa52afc5abd1396e4af720469abb5843a71eb8 (diff)
downloadlinux-faa5673617656ee58369a3cfe4a312cfcdc59c81.tar.gz
bcache: Journal replay fix
The journal replay code starts by finding something that looks like a
valid journal entry, then it does a binary search over the unchecked
region of the journal for the journal entries with the highest sequence
numbers.

Trouble is, the logic was wrong - journal_read_bucket() returns true if
it found journal entries we need, but if the range of journal entries
we're looking for loops around the end of the journal - in that case
journal_read_bucket() could return true when it hadn't found the highest
sequence number we'd seen yet, and in that case the binary search did
the wrong thing. Whoops.

Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Cc: linux-stable <stable@vger.kernel.org> # >= v3.10
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/bcache/journal.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 4b250667bb7f..ba95ab84b2be 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -184,9 +184,14 @@ bsearch:
 		pr_debug("starting binary search, l %u r %u", l, r);
 
 		while (l + 1 < r) {
+			seq = list_entry(list->prev, struct journal_replay,
+					 list)->j.seq;
+
 			m = (l + r) >> 1;
+			read_bucket(m);
 
-			if (read_bucket(m))
+			if (seq != list_entry(list->prev, struct journal_replay,
+					      list)->j.seq)
 				l = m;
 			else
 				r = m;