diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-08-05 21:04:06 (GMT) |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2014-01-08 21:05:06 (GMT) |
commit | b3fa7e77e67e647db3db2166b65083a427d84ed3 (patch) | |
tree | 287ba3124137234e1518208b57717d60aa9eb44b | |
parent | ef71ec00002d92a08eb27e9d036e3d48835b6597 (diff) | |
download | linux-b3fa7e77e67e647db3db2166b65083a427d84ed3.tar.xz |
bcache: Minor journal fix
The real fix is where we check the bytes we need against how much is
remaining - we also need to check for a journal entry bigger than our
buffer, we'll never write those and it would be bad if we tried to read
one.
Also improve the diagnostic messages.
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
-rw-r--r-- | drivers/md/bcache/journal.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index 7eafdf0..29cccc5 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c @@ -44,11 +44,11 @@ static int journal_read_bucket(struct cache *ca, struct list_head *list, closure_init_stack(&cl); - pr_debug("reading %llu", (uint64_t) bucket); + pr_debug("reading %u", bucket_index); while (offset < ca->sb.bucket_size) { reread: left = ca->sb.bucket_size - offset; - len = min_t(unsigned, left, PAGE_SECTORS * 8); + len = min_t(unsigned, left, PAGE_SECTORS << JSET_BITS); bio_reset(bio); bio->bi_iter.bi_sector = bucket + offset; @@ -74,17 +74,26 @@ reread: left = ca->sb.bucket_size - offset; struct list_head *where; size_t blocks, bytes = set_bytes(j); - if (j->magic != jset_magic(&ca->sb)) + if (j->magic != jset_magic(&ca->sb)) { + pr_debug("%u: bad magic", bucket_index); return ret; + } - if (bytes > left << 9) + if (bytes > left << 9 || + bytes > PAGE_SIZE << JSET_BITS) { + pr_info("%u: too big, %zu bytes, offset %u", + bucket_index, bytes, offset); return ret; + } if (bytes > len << 9) goto reread; - if (j->csum != csum_set(j)) + if (j->csum != csum_set(j)) { + pr_info("%u: bad csum, %zu bytes, offset %u", + bucket_index, bytes, offset); return ret; + } blocks = set_blocks(j, ca->set); |