summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/compression.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-07-20 09:29:37 -0400
committerJens Axboe <axboe@fb.com>2015-07-29 10:55:15 -0400
commit4246a0b63bd8f56a1469b12eafeb875b1041a451 (patch)
tree3281bb158d658ef7f208ad380c0ecee600a5ab5e /fs/btrfs/compression.c
parent0034af036554c39eefd14d835a8ec3496ac46712 (diff)
block: add a bi_error field to struct bio
Currently we have two different ways to signal an I/O error on a BIO: (1) by clearing the BIO_UPTODATE flag (2) by returning a Linux errno value to the bi_end_io callback The first one has the drawback of only communicating a single possible error (-EIO), and the second one has the drawback of not beeing persistent when bios are queued up, and are not passed along from child to parent bio in the ever more popular chaining scenario. Having both mechanisms available has the additional drawback of utterly confusing driver authors and introducing bugs where various I/O submitters only deal with one of them, and the others have to add boilerplate code to deal with both kinds of error returns. So add a new bi_error field to store an errno value directly in struct bio and remove the existing mechanisms to clean all this up. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: NeilBrown <neilb@suse.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'fs/btrfs/compression.c')
-rw-r--r--fs/btrfs/compression.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index ce62324c78e7..302266ec2cdb 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -152,7 +152,7 @@ fail:
152 * The compressed pages are freed here, and it must be run 152 * The compressed pages are freed here, and it must be run
153 * in process context 153 * in process context
154 */ 154 */
155static void end_compressed_bio_read(struct bio *bio, int err) 155static void end_compressed_bio_read(struct bio *bio)
156{ 156{
157 struct compressed_bio *cb = bio->bi_private; 157 struct compressed_bio *cb = bio->bi_private;
158 struct inode *inode; 158 struct inode *inode;
@@ -160,7 +160,7 @@ static void end_compressed_bio_read(struct bio *bio, int err)
160 unsigned long index; 160 unsigned long index;
161 int ret; 161 int ret;
162 162
163 if (err) 163 if (bio->bi_error)
164 cb->errors = 1; 164 cb->errors = 1;
165 165
166 /* if there are more bios still pending for this compressed 166 /* if there are more bios still pending for this compressed
@@ -210,7 +210,7 @@ csum_failed:
210 bio_for_each_segment_all(bvec, cb->orig_bio, i) 210 bio_for_each_segment_all(bvec, cb->orig_bio, i)
211 SetPageChecked(bvec->bv_page); 211 SetPageChecked(bvec->bv_page);
212 212
213 bio_endio(cb->orig_bio, 0); 213 bio_endio(cb->orig_bio);
214 } 214 }
215 215
216 /* finally free the cb struct */ 216 /* finally free the cb struct */
@@ -266,7 +266,7 @@ static noinline void end_compressed_writeback(struct inode *inode,
266 * This also calls the writeback end hooks for the file pages so that 266 * This also calls the writeback end hooks for the file pages so that
267 * metadata and checksums can be updated in the file. 267 * metadata and checksums can be updated in the file.
268 */ 268 */
269static void end_compressed_bio_write(struct bio *bio, int err) 269static void end_compressed_bio_write(struct bio *bio)
270{ 270{
271 struct extent_io_tree *tree; 271 struct extent_io_tree *tree;
272 struct compressed_bio *cb = bio->bi_private; 272 struct compressed_bio *cb = bio->bi_private;
@@ -274,7 +274,7 @@ static void end_compressed_bio_write(struct bio *bio, int err)
274 struct page *page; 274 struct page *page;
275 unsigned long index; 275 unsigned long index;
276 276
277 if (err) 277 if (bio->bi_error)
278 cb->errors = 1; 278 cb->errors = 1;
279 279
280 /* if there are more bios still pending for this compressed 280 /* if there are more bios still pending for this compressed
@@ -293,7 +293,7 @@ static void end_compressed_bio_write(struct bio *bio, int err)
293 cb->start, 293 cb->start,
294 cb->start + cb->len - 1, 294 cb->start + cb->len - 1,
295 NULL, 295 NULL,
296 err ? 0 : 1); 296 bio->bi_error ? 0 : 1);
297 cb->compressed_pages[0]->mapping = NULL; 297 cb->compressed_pages[0]->mapping = NULL;
298 298
299 end_compressed_writeback(inode, cb); 299 end_compressed_writeback(inode, cb);
@@ -697,8 +697,10 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
697 697
698 ret = btrfs_map_bio(root, READ, comp_bio, 698 ret = btrfs_map_bio(root, READ, comp_bio,
699 mirror_num, 0); 699 mirror_num, 0);
700 if (ret) 700 if (ret) {
701 bio_endio(comp_bio, ret); 701 bio->bi_error = ret;
702 bio_endio(comp_bio);
703 }
702 704
703 bio_put(comp_bio); 705 bio_put(comp_bio);
704 706
@@ -724,8 +726,10 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
724 } 726 }
725 727
726 ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0); 728 ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0);
727 if (ret) 729 if (ret) {
728 bio_endio(comp_bio, ret); 730 bio->bi_error = ret;
731 bio_endio(comp_bio);
732 }
729 733
730 bio_put(comp_bio); 734 bio_put(comp_bio);
731 return 0; 735 return 0;