[PATCH] bcache: correct journal bucket reading

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Tang Junhui <tang.junhui@xxxxxxxxxx>

There are 3 steps to read out all journal buckets.
1) Try to get a valid journal bucket by golden ratio hash or
falling back to linear search. For an example, NNNYYYNN, each
character represents a bucket, Y represents a valid journal
bucket, and N is not. After step 1, we may get the 5th bucket
as a valid journal bucket, and the 7th bucket as an invalid
bucket.
2) Try to get the latest valid journal bucket by Binary search.
After this steps, in NNNYYYNN, we can get the 6th as the latest
valid bucket.
3) Read the journal form tail to front in the 6th bucket.

But actually, since the journal bucket is a ring, the bucket
can be like YYYNNNYY, which means the first valid journal in
the 7th bucket, and the last valid journal in third bucket, in
this case, we may get a valid journal in the 7th bucket by step
1, but in step 2 we call find_next_bit(bitmap,
ca->sb.njournal_buckets, l + 1) to find the first invalid bucket
after the 7th bucket, because all these buckets is valid, so no
bit 1 in bitmap, thus find_next_bit() function would return with
ca->sb.njournal_buckets (8). So, in step 3), bcache only read
journal in 7th bucket, the journal in 8th bucket and the first
to the third buckets are lost.

Signed-off-by: Tang Junhui <tang.junhui@xxxxxxxxxx>
---
 drivers/md/bcache/journal.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
 mode change 100644 => 100755 drivers/md/bcache/journal.c

diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
old mode 100644
new mode 100755
index 0352d05..8a549fb
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -199,14 +199,17 @@ int bch_journal_read(struct cache_set *c, struct list_head *list)
 		/* Binary search */
 		m = l;
 		r = find_next_bit(bitmap, ca->sb.njournal_buckets, l + 1);
-		pr_debug("starting binary search, l %u r %u", l, r);
+		if (r == ca->sb.njournal_buckets && 
+		    !test_bit(r, bitmap))
+			r = ca->sb.njournal_buckets + find_next_bit(bitmap, ca->sb.njournal_buckets, 0);
+		pr_debug("starting binary search, l %u r %u", l, r % ca->sb.njournal_buckets);
 
 		while (l + 1 < r) {
 			seq = list_entry(list->prev, struct journal_replay,
 					 list)->j.seq;
 
 			m = (l + r) >> 1;
-			read_bucket(m);
+			read_bucket(m % ca->sb.njournal_buckets);
 
 			if (seq != list_entry(list->prev, struct journal_replay,
 					      list)->j.seq)
@@ -219,6 +222,7 @@ int bch_journal_read(struct cache_set *c, struct list_head *list)
 		 * Read buckets in reverse order until we stop finding more
 		 * journal entries
 		 */
+		m = m % ca->sb.njournal_buckets;
 		pr_debug("finishing up: m %u njournal_buckets %u",
 			 m, ca->sb.njournal_buckets);
 		l = m;
-- 
1.8.3.1




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux