aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.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/volumes.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/volumes.c')
-rw-r--r--fs/btrfs/volumes.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index fbe7c104531c..8f2ca18c71f4 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -5741,23 +5741,23 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
5741 return 0; 5741 return 0;
5742} 5742}
5743 5743
5744static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio, int err) 5744static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio)
5745{ 5745{
5746 bio->bi_private = bbio->private; 5746 bio->bi_private = bbio->private;
5747 bio->bi_end_io = bbio->end_io; 5747 bio->bi_end_io = bbio->end_io;
5748 bio_endio(bio, err); 5748 bio_endio(bio);
5749 5749
5750 btrfs_put_bbio(bbio); 5750 btrfs_put_bbio(bbio);
5751} 5751}
5752 5752
5753static void btrfs_end_bio(struct bio *bio, int err) 5753static void btrfs_end_bio(struct bio *bio)
5754{ 5754{
5755 struct btrfs_bio *bbio = bio->bi_private; 5755 struct btrfs_bio *bbio = bio->bi_private;
5756 int is_orig_bio = 0; 5756 int is_orig_bio = 0;
5757 5757
5758 if (err) { 5758 if (bio->bi_error) {
5759 atomic_inc(&bbio->error); 5759 atomic_inc(&bbio->error);
5760 if (err == -EIO || err == -EREMOTEIO) { 5760 if (bio->bi_error == -EIO || bio->bi_error == -EREMOTEIO) {
5761 unsigned int stripe_index = 5761 unsigned int stripe_index =
5762 btrfs_io_bio(bio)->stripe_index; 5762 btrfs_io_bio(bio)->stripe_index;
5763 struct btrfs_device *dev; 5763 struct btrfs_device *dev;
@@ -5795,17 +5795,16 @@ static void btrfs_end_bio(struct bio *bio, int err)
5795 * beyond the tolerance of the btrfs bio 5795 * beyond the tolerance of the btrfs bio
5796 */ 5796 */
5797 if (atomic_read(&bbio->error) > bbio->max_errors) { 5797 if (atomic_read(&bbio->error) > bbio->max_errors) {
5798 err = -EIO; 5798 bio->bi_error = -EIO;
5799 } else { 5799 } else {
5800 /* 5800 /*
5801 * this bio is actually up to date, we didn't 5801 * this bio is actually up to date, we didn't
5802 * go over the max number of errors 5802 * go over the max number of errors
5803 */ 5803 */
5804 set_bit(BIO_UPTODATE, &bio->bi_flags); 5804 bio->bi_error = 0;
5805 err = 0;
5806 } 5805 }
5807 5806
5808 btrfs_end_bbio(bbio, bio, err); 5807 btrfs_end_bbio(bbio, bio);
5809 } else if (!is_orig_bio) { 5808 } else if (!is_orig_bio) {
5810 bio_put(bio); 5809 bio_put(bio);
5811 } 5810 }
@@ -5826,7 +5825,7 @@ static noinline void btrfs_schedule_bio(struct btrfs_root *root,
5826 struct btrfs_pending_bios *pending_bios; 5825 struct btrfs_pending_bios *pending_bios;
5827 5826
5828 if (device->missing || !device->bdev) { 5827 if (device->missing || !device->bdev) {
5829 bio_endio(bio, -EIO); 5828 bio_io_error(bio);
5830 return; 5829 return;
5831 } 5830 }
5832 5831
@@ -5973,8 +5972,8 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
5973 5972
5974 btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; 5973 btrfs_io_bio(bio)->mirror_num = bbio->mirror_num;
5975 bio->bi_iter.bi_sector = logical >> 9; 5974 bio->bi_iter.bi_sector = logical >> 9;
5976 5975 bio->bi_error = -EIO;
5977 btrfs_end_bbio(bbio, bio, -EIO); 5976 btrfs_end_bbio(bbio, bio);
5978 } 5977 }
5979} 5978}
5980 5979