aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2017-09-20 19:50:19 -0400
committerDavid Sterba <dsterba@suse.com>2017-09-26 08:53:26 -0400
commite6311f240c946788131ba2b97e14f37312688072 (patch)
treefdd78165cfdd0d426f7c0b86b28e910716d88821
parentcf1167d5c1abf3bc42b2a1562bfa7937c05337e2 (diff)
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>
-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)
108 struct page *page; 108 struct page *page;
109 unsigned long index; 109 unsigned long index;
110 unsigned int mirror = btrfs_io_bio(bio)->mirror_num; 110 unsigned int mirror = btrfs_io_bio(bio)->mirror_num;
111 int ret; 111 int ret = 0;
112 112
113 if (bio->bi_status) 113 if (bio->bi_status)
114 cb->errors = 1; 114 cb->errors = 1;
@@ -127,6 +127,13 @@ static void end_compressed_bio_read(struct bio *bio)
127 btrfs_io_bio(cb->orig_bio)->mirror_num = mirror; 127 btrfs_io_bio(cb->orig_bio)->mirror_num = mirror;
128 cb->mirror_num = mirror; 128 cb->mirror_num = mirror;
129 129
130 /*
131 * Some IO in this cb have failed, just skip checksum as there
132 * is no way it could be correct.
133 */
134 if (cb->errors == 1)
135 goto csum_failed;
136
130 inode = cb->inode; 137 inode = cb->inode;
131 ret = check_compressed_csum(BTRFS_I(inode), cb, 138 ret = check_compressed_csum(BTRFS_I(inode), cb,
132 (u64)bio->bi_iter.bi_sector << 9); 139 (u64)bio->bi_iter.bi_sector << 9);