diff options
Diffstat (limited to 'fs/btrfs/compression.c')
-rw-r--r-- | fs/btrfs/compression.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index b51d23f5cafa..280384bf34f1 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -107,7 +107,8 @@ static void end_compressed_bio_read(struct bio *bio) | |||
107 | struct inode *inode; | 107 | struct inode *inode; |
108 | struct page *page; | 108 | struct page *page; |
109 | unsigned long index; | 109 | unsigned long index; |
110 | int ret; | 110 | unsigned int mirror = btrfs_io_bio(bio)->mirror_num; |
111 | int ret = 0; | ||
111 | 112 | ||
112 | if (bio->bi_status) | 113 | if (bio->bi_status) |
113 | cb->errors = 1; | 114 | cb->errors = 1; |
@@ -118,6 +119,21 @@ static void end_compressed_bio_read(struct bio *bio) | |||
118 | if (!refcount_dec_and_test(&cb->pending_bios)) | 119 | if (!refcount_dec_and_test(&cb->pending_bios)) |
119 | goto out; | 120 | goto out; |
120 | 121 | ||
122 | /* | ||
123 | * Record the correct mirror_num in cb->orig_bio so that | ||
124 | * read-repair can work properly. | ||
125 | */ | ||
126 | ASSERT(btrfs_io_bio(cb->orig_bio)); | ||
127 | btrfs_io_bio(cb->orig_bio)->mirror_num = mirror; | ||
128 | cb->mirror_num = mirror; | ||
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 | |||
121 | inode = cb->inode; | 137 | inode = cb->inode; |
122 | ret = check_compressed_csum(BTRFS_I(inode), cb, | 138 | ret = check_compressed_csum(BTRFS_I(inode), cb, |
123 | (u64)bio->bi_iter.bi_sector << 9); | 139 | (u64)bio->bi_iter.bi_sector << 9); |