diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-09-29 18:45:39 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-01-18 21:40:27 -0900 |
commit | 28055cc2788d388fd7ca15d79feb2ecc20c1ca77 (patch) | |
tree | 8906de8d888adcfe2fe1e00f4261ec009687b99f | |
parent | 60c13f99393aa182143d1f68c3a5109a810abfb5 (diff) |
bcache: more useful checksum errors
-rw-r--r-- | drivers/md/bcache/error.h | 2 | ||||
-rw-r--r-- | drivers/md/bcache/io.c | 26 |
2 files changed, 18 insertions, 10 deletions
diff --git a/drivers/md/bcache/error.h b/drivers/md/bcache/error.h index ef93eebc8f1f..268c550f7f7c 100644 --- a/drivers/md/bcache/error.h +++ b/drivers/md/bcache/error.h @@ -171,7 +171,7 @@ do { \ #define cache_nonfatal_io_err_on(cond, ca, ...) \ ({ \ - int _ret = !!(cond); \ + bool _ret = (cond); \ \ if (_ret) \ cache_nonfatal_io_error(ca, __VA_ARGS__); \ diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c index 165c640fe2cd..f9a92775afa0 100644 --- a/drivers/md/bcache/io.c +++ b/drivers/md/bcache/io.c @@ -850,6 +850,7 @@ static int bio_checksum_uncompress(struct cache_set *c, struct bio *src = &rbio->bio; struct bio *dst = &bch_rbio_parent(rbio)->bio; struct bvec_iter dst_iter = rbio->parent_iter; + u64 csum; int ret = 0; /* @@ -866,23 +867,30 @@ static int bio_checksum_uncompress(struct cache_set *c, src->bi_iter = rbio->parent_iter; } - if (rbio->crc.csum_type != BCH_CSUM_NONE && - rbio->crc.csum != bch_checksum_bio(src, rbio->crc.csum_type)) { - cache_nonfatal_io_error(rbio->ca, "checksum error"); - return -EIO; - } + csum = bch_checksum_bio(src, rbio->crc.csum_type); + if (cache_nonfatal_io_err_on(rbio->crc.csum != csum, rbio->ca, + "data checksum error, inode %llu offset %llu: expected %0llx got %0llx (type %u)", + rbio->inode, (u64) rbio->parent_iter.bi_sector << 9, + rbio->crc.csum, csum, rbio->crc.csum_type)) + ret = -EIO; + /* + * If there was a checksum error, still copy the data back - unless it + * was compressed, we don't want to decompress bad data: + */ if (rbio->crc.compression_type != BCH_COMPRESSION_NONE) { - ret = bch_bio_uncompress(c, src, dst, dst_iter, rbio->crc); + if (!ret) { + ret = bch_bio_uncompress(c, src, dst, + dst_iter, rbio->crc); + if (ret) + __bcache_io_error(c, "decompression error"); + } } else if (rbio->bounce) { bio_advance(src, rbio->crc.offset << 9); bio_copy_data_iter(dst, dst_iter, src, src->bi_iter); } - if (ret) - __bcache_io_error(c, "decompression error"); - return ret; } |