summaryrefslogtreecommitdiffstats
path: root/block/bio.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 /block/bio.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 'block/bio.c')
-rw-r--r--block/bio.c43
1 files changed, 18 insertions, 25 deletions
diff --git a/block/bio.c b/block/bio.c
index 2a00d349cd68..a23f489f398f 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -269,7 +269,6 @@ static void bio_free(struct bio *bio)
269void bio_init(struct bio *bio) 269void bio_init(struct bio *bio)
270{ 270{
271 memset(bio, 0, sizeof(*bio)); 271 memset(bio, 0, sizeof(*bio));
272 bio->bi_flags = 1 << BIO_UPTODATE;
273 atomic_set(&bio->__bi_remaining, 1); 272 atomic_set(&bio->__bi_remaining, 1);
274 atomic_set(&bio->__bi_cnt, 1); 273 atomic_set(&bio->__bi_cnt, 1);
275} 274}
@@ -292,14 +291,17 @@ void bio_reset(struct bio *bio)
292 __bio_free(bio); 291 __bio_free(bio);
293 292
294 memset(bio, 0, BIO_RESET_BYTES); 293 memset(bio, 0, BIO_RESET_BYTES);
295 bio->bi_flags = flags | (1 << BIO_UPTODATE); 294 bio->bi_flags = flags;
296 atomic_set(&bio->__bi_remaining, 1); 295 atomic_set(&bio->__bi_remaining, 1);
297} 296}
298EXPORT_SYMBOL(bio_reset); 297EXPORT_SYMBOL(bio_reset);
299 298
300static void bio_chain_endio(struct bio *bio, int error) 299static void bio_chain_endio(struct bio *bio)
301{ 300{
302 bio_endio(bio->bi_private, error); 301 struct bio *parent = bio->bi_private;
302
303 parent->bi_error = bio->bi_error;
304 bio_endio(parent);
303 bio_put(bio); 305 bio_put(bio);
304} 306}
305 307
@@ -896,11 +898,11 @@ struct submit_bio_ret {
896 int error; 898 int error;
897}; 899};
898 900
899static void submit_bio_wait_endio(struct bio *bio, int error) 901static void submit_bio_wait_endio(struct bio *bio)
900{ 902{
901 struct submit_bio_ret *ret = bio->bi_private; 903 struct submit_bio_ret *ret = bio->bi_private;
902 904
903 ret->error = error; 905 ret->error = bio->bi_error;
904 complete(&ret->event); 906 complete(&ret->event);
905} 907}
906 908
@@ -1445,7 +1447,7 @@ void bio_unmap_user(struct bio *bio)
1445} 1447}
1446EXPORT_SYMBOL(bio_unmap_user); 1448EXPORT_SYMBOL(bio_unmap_user);
1447 1449
1448static void bio_map_kern_endio(struct bio *bio, int err) 1450static void bio_map_kern_endio(struct bio *bio)
1449{ 1451{
1450 bio_put(bio); 1452 bio_put(bio);
1451} 1453}
@@ -1501,13 +1503,13 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
1501} 1503}
1502EXPORT_SYMBOL(bio_map_kern); 1504EXPORT_SYMBOL(bio_map_kern);
1503 1505
1504static void bio_copy_kern_endio(struct bio *bio, int err) 1506static void bio_copy_kern_endio(struct bio *bio)
1505{ 1507{
1506 bio_free_pages(bio); 1508 bio_free_pages(bio);
1507 bio_put(bio); 1509 bio_put(bio);
1508} 1510}
1509 1511
1510static void bio_copy_kern_endio_read(struct bio *bio, int err) 1512static void bio_copy_kern_endio_read(struct bio *bio)
1511{ 1513{
1512 char *p = bio->bi_private; 1514 char *p = bio->bi_private;
1513 struct bio_vec *bvec; 1515 struct bio_vec *bvec;
@@ -1518,7 +1520,7 @@ static void bio_copy_kern_endio_read(struct bio *bio, int err)
1518 p += bvec->bv_len; 1520 p += bvec->bv_len;
1519 } 1521 }
1520 1522
1521 bio_copy_kern_endio(bio, err); 1523 bio_copy_kern_endio(bio);
1522} 1524}
1523 1525
1524/** 1526/**
@@ -1778,25 +1780,15 @@ static inline bool bio_remaining_done(struct bio *bio)
1778/** 1780/**
1779 * bio_endio - end I/O on a bio 1781 * bio_endio - end I/O on a bio
1780 * @bio: bio 1782 * @bio: bio
1781 * @error: error, if any
1782 * 1783 *
1783 * Description: 1784 * Description:
1784 * bio_endio() will end I/O on the whole bio. bio_endio() is the 1785 * bio_endio() will end I/O on the whole bio. bio_endio() is the preferred
1785 * preferred way to end I/O on a bio, it takes care of clearing 1786 * way to end I/O on a bio. No one should call bi_end_io() directly on a
1786 * BIO_UPTODATE on error. @error is 0 on success, and and one of the 1787 * bio unless they own it and thus know that it has an end_io function.
1787 * established -Exxxx (-EIO, for instance) error values in case
1788 * something went wrong. No one should call bi_end_io() directly on a
1789 * bio unless they own it and thus know that it has an end_io
1790 * function.
1791 **/ 1788 **/
1792void bio_endio(struct bio *bio, int error) 1789void bio_endio(struct bio *bio)
1793{ 1790{
1794 while (bio) { 1791 while (bio) {
1795 if (error)
1796 clear_bit(BIO_UPTODATE, &bio->bi_flags);
1797 else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
1798 error = -EIO;
1799
1800 if (unlikely(!bio_remaining_done(bio))) 1792 if (unlikely(!bio_remaining_done(bio)))
1801 break; 1793 break;
1802 1794
@@ -1810,11 +1802,12 @@ void bio_endio(struct bio *bio, int error)
1810 */ 1802 */
1811 if (bio->bi_end_io == bio_chain_endio) { 1803 if (bio->bi_end_io == bio_chain_endio) {
1812 struct bio *parent = bio->bi_private; 1804 struct bio *parent = bio->bi_private;
1805 parent->bi_error = bio->bi_error;
1813 bio_put(bio); 1806 bio_put(bio);
1814 bio = parent; 1807 bio = parent;
1815 } else { 1808 } else {
1816 if (bio->bi_end_io) 1809 if (bio->bi_end_io)
1817 bio->bi_end_io(bio, error); 1810 bio->bi_end_io(bio);
1818 bio = NULL; 1811 bio = NULL;
1819 } 1812 }
1820 } 1813 }