aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bcache
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-07-12 01:42:14 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-28 19:30:10 -0400
commit5e20e8b3713b8a5941891db2626c9eecd3c0888c (patch)
tree56018d65da18a1618cf29eddf37a317d260eee00 /drivers/md/bcache
parent99e56bf5abce5131746397a2ce551fd92ca8f342 (diff)
bcache: Journal replay fix
commit faa5673617656ee58369a3cfe4a312cfcdc59c81 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/md/bcache')
-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 8c8dfdcd9d4c..8a54d3b4f517 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -182,9 +182,14 @@ bsearch:
182 pr_debug("starting binary search, l %u r %u", l, r); 182 pr_debug("starting binary search, l %u r %u", l, r);
183 183
184 while (l + 1 < r) { 184 while (l + 1 < r) {
185 seq = list_entry(list->prev, struct journal_replay,
186 list)->j.seq;
187
185 m = (l + r) >> 1; 188 m = (l + r) >> 1;
189 read_bucket(m);
186 190
187 if (read_bucket(m)) 191 if (seq != list_entry(list->prev, struct journal_replay,
192 list)->j.seq)
188 l = m; 193 l = m;
189 else 194 else
190 r = m; 195 r = m;