aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2017-09-20 17:50:19 -0600
committerDavid Sterba <dsterba@suse.com>2017-09-26 14:53:26 +0200
commite6311f240c946788131ba2b97e14f37312688072 (patch)
treefdd78165cfdd0d426f7c0b86b28e910716d88821 /fs/btrfs
parentBtrfs: fix kernel oops while reading compressed data (diff)
downloadlinux-dev-e6311f240c946788131ba2b97e14f37312688072.tar.xz
linux-dev-e6311f240c946788131ba2b97e14f37312688072.zip
Btrfs: skip checksum when reading compressed data if some IO have failed
Currently even if the underlying disk reports failure on IO, compressed read endio still gets to verify checksum and reports it as a checksum error. In fact, if some IO have failed during reading a compressed data extent , there's no way the checksum could match, therefore, we can skip that in order to return error quickly to the upper layer. Please note that we need to do this after recording the failed mirror index so that read-repair in the upper layer's endio can work properly. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Tested-by: Paul Jones <paul@pauljones.id.au> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/compression.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index c6aa53c4c102..fc31af98a41b 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -108,7 +108,7 @@ static void end_compressed_bio_read(struct bio *bio)
struct page *page;
unsigned long index;
unsigned int mirror = btrfs_io_bio(bio)->mirror_num;
- int ret;
+ int ret = 0;
if (bio->bi_status)
cb->errors = 1;
@@ -127,6 +127,13 @@ static void end_compressed_bio_read(struct bio *bio)
btrfs_io_bio(cb->orig_bio)->mirror_num = mirror;
cb->mirror_num = mirror;
+ /*
+ * Some IO in this cb have failed, just skip checksum as there
+ * is no way it could be correct.
+ */
+ if (cb->errors == 1)
+ goto csum_failed;
+
inode = cb->inode;
ret = check_compressed_csum(BTRFS_I(inode), cb,
(u64)bio->bi_iter.bi_sector << 9);