summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bcache/error.h2
-rw-r--r--drivers/md/bcache/io.c26
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;
}