Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c426c4fd authored by Kent Overstreet's avatar Kent Overstreet Committed by Linus Torvalds
Browse files

bcache: Fix for when no journal entries are found



The journal replay code didn't handle this case, causing it to go into
an infinite loop...

Signed-off-by: default avatarKent Overstreet <kmo@daterainc.com>
Cc: linux-stable <stable@vger.kernel.org> # >= v3.10
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent aee6f1cf
Loading
Loading
Loading
Loading
+18 −12
Original line number Diff line number Diff line
@@ -153,7 +153,8 @@ int bch_journal_read(struct cache_set *c, struct list_head *list,
		bitmap_zero(bitmap, SB_JOURNAL_BUCKETS);
		pr_debug("%u journal buckets", ca->sb.njournal_buckets);

		/* Read journal buckets ordered by golden ratio hash to quickly
		/*
		 * Read journal buckets ordered by golden ratio hash to quickly
		 * find a sequence of buckets with valid journal entries
		 */
		for (i = 0; i < ca->sb.njournal_buckets; i++) {
@@ -166,18 +167,20 @@ int bch_journal_read(struct cache_set *c, struct list_head *list,
				goto bsearch;
		}

		/* If that fails, check all the buckets we haven't checked
		/*
		 * If that fails, check all the buckets we haven't checked
		 * already
		 */
		pr_debug("falling back to linear search");

		for (l = 0; l < ca->sb.njournal_buckets; l++) {
			if (test_bit(l, bitmap))
				continue;

		for (l = find_first_zero_bit(bitmap, ca->sb.njournal_buckets);
		     l < ca->sb.njournal_buckets;
		     l = find_next_zero_bit(bitmap, ca->sb.njournal_buckets, l + 1))
			if (read_bucket(l))
				goto bsearch;
		}

		if (list_empty(list))
			continue;
bsearch:
		/* Binary search */
		m = r = find_next_bit(bitmap, ca->sb.njournal_buckets, l + 1);
@@ -197,10 +200,12 @@ int bch_journal_read(struct cache_set *c, struct list_head *list,
				r = m;
		}

		/* Read buckets in reverse order until we stop finding more
		/*
		 * Read buckets in reverse order until we stop finding more
		 * journal entries
		 */
		pr_debug("finishing up");
		pr_debug("finishing up: m %u njournal_buckets %u",
			 m, ca->sb.njournal_buckets);
		l = m;

		while (1) {
@@ -228,6 +233,7 @@ int bch_journal_read(struct cache_set *c, struct list_head *list,
			}
	}

	if (!list_empty(list))
		c->journal.seq = list_entry(list->prev,
					    struct journal_replay,
					    list)->j.seq;