aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.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/inode.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/inode.c')
-rw-r--r--fs/btrfs/inode.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b33c0cf02668..6b8becfe2057 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1845,8 +1845,10 @@ static int __btrfs_submit_bio_done(struct inode *inode, int rw, struct bio *bio,
1845 int ret; 1845 int ret;
1846 1846
1847 ret = btrfs_map_bio(root, rw, bio, mirror_num, 1); 1847 ret = btrfs_map_bio(root, rw, bio, mirror_num, 1);
1848 if (ret) 1848 if (ret) {
1849 bio_endio(bio, ret); 1849 bio->bi_error = ret;
1850 bio_endio(bio);
1851 }
1850 return ret; 1852 return ret;
1851} 1853}
1852 1854
@@ -1906,8 +1908,10 @@ mapit:
1906 ret = btrfs_map_bio(root, rw, bio, mirror_num, 0); 1908 ret = btrfs_map_bio(root, rw, bio, mirror_num, 0);
1907 1909
1908out: 1910out:
1909 if (ret < 0) 1911 if (ret < 0) {
1910 bio_endio(bio, ret); 1912 bio->bi_error = ret;
1913 bio_endio(bio);
1914 }
1911 return ret; 1915 return ret;
1912} 1916}
1913 1917
@@ -7689,13 +7693,13 @@ struct btrfs_retry_complete {
7689 int uptodate; 7693 int uptodate;
7690}; 7694};
7691 7695
7692static void btrfs_retry_endio_nocsum(struct bio *bio, int err) 7696static void btrfs_retry_endio_nocsum(struct bio *bio)
7693{ 7697{
7694 struct btrfs_retry_complete *done = bio->bi_private; 7698 struct btrfs_retry_complete *done = bio->bi_private;
7695 struct bio_vec *bvec; 7699 struct bio_vec *bvec;
7696 int i; 7700 int i;
7697 7701
7698 if (err) 7702 if (bio->bi_error)
7699 goto end; 7703 goto end;
7700 7704
7701 done->uptodate = 1; 7705 done->uptodate = 1;
@@ -7744,7 +7748,7 @@ try_again:
7744 return 0; 7748 return 0;
7745} 7749}
7746 7750
7747static void btrfs_retry_endio(struct bio *bio, int err) 7751static void btrfs_retry_endio(struct bio *bio)
7748{ 7752{
7749 struct btrfs_retry_complete *done = bio->bi_private; 7753 struct btrfs_retry_complete *done = bio->bi_private;
7750 struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); 7754 struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
@@ -7753,7 +7757,7 @@ static void btrfs_retry_endio(struct bio *bio, int err)
7753 int ret; 7757 int ret;
7754 int i; 7758 int i;
7755 7759
7756 if (err) 7760 if (bio->bi_error)
7757 goto end; 7761 goto end;
7758 7762
7759 uptodate = 1; 7763 uptodate = 1;
@@ -7836,12 +7840,13 @@ static int btrfs_subio_endio_read(struct inode *inode,
7836 } 7840 }
7837} 7841}
7838 7842
7839static void btrfs_endio_direct_read(struct bio *bio, int err) 7843static void btrfs_endio_direct_read(struct bio *bio)
7840{ 7844{
7841 struct btrfs_dio_private *dip = bio->bi_private; 7845 struct btrfs_dio_private *dip = bio->bi_private;
7842 struct inode *inode = dip->inode; 7846 struct inode *inode = dip->inode;
7843 struct bio *dio_bio; 7847 struct bio *dio_bio;
7844 struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); 7848 struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
7849 int err = bio->bi_error;
7845 7850
7846 if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED) 7851 if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED)
7847 err = btrfs_subio_endio_read(inode, io_bio, err); 7852 err = btrfs_subio_endio_read(inode, io_bio, err);
@@ -7852,17 +7857,14 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
7852 7857
7853 kfree(dip); 7858 kfree(dip);
7854 7859
7855 /* If we had a csum failure make sure to clear the uptodate flag */ 7860 dio_end_io(dio_bio, bio->bi_error);
7856 if (err)
7857 clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
7858 dio_end_io(dio_bio, err);
7859 7861
7860 if (io_bio->end_io) 7862 if (io_bio->end_io)
7861 io_bio->end_io(io_bio, err); 7863 io_bio->end_io(io_bio, err);
7862 bio_put(bio); 7864 bio_put(bio);
7863} 7865}
7864 7866
7865static void btrfs_endio_direct_write(struct bio *bio, int err) 7867static void btrfs_endio_direct_write(struct bio *bio)
7866{ 7868{
7867 struct btrfs_dio_private *dip = bio->bi_private; 7869 struct btrfs_dio_private *dip = bio->bi_private;
7868 struct inode *inode = dip->inode; 7870 struct inode *inode = dip->inode;
@@ -7876,7 +7878,8 @@ static void btrfs_endio_direct_write(struct bio *bio, int err)
7876again: 7878again:
7877 ret = btrfs_dec_test_first_ordered_pending(inode, &ordered, 7879 ret = btrfs_dec_test_first_ordered_pending(inode, &ordered,
7878 &ordered_offset, 7880 &ordered_offset,
7879 ordered_bytes, !err); 7881 ordered_bytes,
7882 !bio->bi_error);
7880 if (!ret) 7883 if (!ret)
7881 goto out_test; 7884 goto out_test;
7882 7885
@@ -7899,10 +7902,7 @@ out_test:
7899 7902
7900 kfree(dip); 7903 kfree(dip);
7901 7904
7902 /* If we had an error make sure to clear the uptodate flag */ 7905 dio_end_io(dio_bio, bio->bi_error);
7903 if (err)
7904 clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
7905 dio_end_io(dio_bio, err);
7906 bio_put(bio); 7906 bio_put(bio);
7907} 7907}
7908 7908
@@ -7917,9 +7917,10 @@ static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw,
7917 return 0; 7917 return 0;
7918} 7918}
7919 7919
7920static void btrfs_end_dio_bio(struct bio *bio, int err) 7920static void btrfs_end_dio_bio(struct bio *bio)
7921{ 7921{
7922 struct btrfs_dio_private *dip = bio->bi_private; 7922 struct btrfs_dio_private *dip = bio->bi_private;
7923 int err = bio->bi_error;
7923 7924
7924 if (err) 7925 if (err)
7925 btrfs_warn(BTRFS_I(dip->inode)->root->fs_info, 7926 btrfs_warn(BTRFS_I(dip->inode)->root->fs_info,
@@ -7948,8 +7949,8 @@ static void btrfs_end_dio_bio(struct bio *bio, int err)
7948 if (dip->errors) { 7949 if (dip->errors) {
7949 bio_io_error(dip->orig_bio); 7950 bio_io_error(dip->orig_bio);
7950 } else { 7951 } else {
7951 set_bit(BIO_UPTODATE, &dip->dio_bio->bi_flags); 7952 dip->dio_bio->bi_error = 0;
7952 bio_endio(dip->orig_bio, 0); 7953 bio_endio(dip->orig_bio);
7953 } 7954 }
7954out: 7955out:
7955 bio_put(bio); 7956 bio_put(bio);
@@ -8220,7 +8221,8 @@ free_ordered:
8220 * callbacks - they require an allocated dip and a clone of dio_bio. 8221 * callbacks - they require an allocated dip and a clone of dio_bio.
8221 */ 8222 */
8222 if (io_bio && dip) { 8223 if (io_bio && dip) {
8223 bio_endio(io_bio, ret); 8224 io_bio->bi_error = -EIO;
8225 bio_endio(io_bio);
8224 /* 8226 /*
8225 * The end io callbacks free our dip, do the final put on io_bio 8227 * The end io callbacks free our dip, do the final put on io_bio
8226 * and all the cleanup and final put for dio_bio (through 8228 * and all the cleanup and final put for dio_bio (through
@@ -8247,7 +8249,7 @@ free_ordered:
8247 unlock_extent(&BTRFS_I(inode)->io_tree, file_offset, 8249 unlock_extent(&BTRFS_I(inode)->io_tree, file_offset,
8248 file_offset + dio_bio->bi_iter.bi_size - 1); 8250 file_offset + dio_bio->bi_iter.bi_size - 1);
8249 } 8251 }
8250 clear_bit(BIO_UPTODATE, &dio_bio->bi_flags); 8252 dio_bio->bi_error = -EIO;
8251 /* 8253 /*
8252 * Releases and cleans up our dio_bio, no need to bio_put() 8254 * Releases and cleans up our dio_bio, no need to bio_put()
8253 * nor bio_endio()/bio_io_error() against dio_bio. 8255 * nor bio_endio()/bio_io_error() against dio_bio.