aboutsummaryrefslogtreecommitdiffstats
path: root/fs/direct-io.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/direct-io.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/direct-io.c')
-rw-r--r--fs/direct-io.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 745d2342651a..e1639c8c14d5 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -285,7 +285,7 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio);
285/* 285/*
286 * Asynchronous IO callback. 286 * Asynchronous IO callback.
287 */ 287 */
288static void dio_bio_end_aio(struct bio *bio, int error) 288static void dio_bio_end_aio(struct bio *bio)
289{ 289{
290 struct dio *dio = bio->bi_private; 290 struct dio *dio = bio->bi_private;
291 unsigned long remaining; 291 unsigned long remaining;
@@ -318,7 +318,7 @@ static void dio_bio_end_aio(struct bio *bio, int error)
318 * During I/O bi_private points at the dio. After I/O, bi_private is used to 318 * During I/O bi_private points at the dio. After I/O, bi_private is used to
319 * implement a singly-linked list of completed BIOs, at dio->bio_list. 319 * implement a singly-linked list of completed BIOs, at dio->bio_list.
320 */ 320 */
321static void dio_bio_end_io(struct bio *bio, int error) 321static void dio_bio_end_io(struct bio *bio)
322{ 322{
323 struct dio *dio = bio->bi_private; 323 struct dio *dio = bio->bi_private;
324 unsigned long flags; 324 unsigned long flags;
@@ -345,9 +345,9 @@ void dio_end_io(struct bio *bio, int error)
345 struct dio *dio = bio->bi_private; 345 struct dio *dio = bio->bi_private;
346 346
347 if (dio->is_async) 347 if (dio->is_async)
348 dio_bio_end_aio(bio, error); 348 dio_bio_end_aio(bio);
349 else 349 else
350 dio_bio_end_io(bio, error); 350 dio_bio_end_io(bio);
351} 351}
352EXPORT_SYMBOL_GPL(dio_end_io); 352EXPORT_SYMBOL_GPL(dio_end_io);
353 353
@@ -457,11 +457,10 @@ static struct bio *dio_await_one(struct dio *dio)
457 */ 457 */
458static int dio_bio_complete(struct dio *dio, struct bio *bio) 458static int dio_bio_complete(struct dio *dio, struct bio *bio)
459{ 459{
460 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
461 struct bio_vec *bvec; 460 struct bio_vec *bvec;
462 unsigned i; 461 unsigned i;
463 462
464 if (!uptodate) 463 if (bio->bi_error)
465 dio->io_error = -EIO; 464 dio->io_error = -EIO;
466 465
467 if (dio->is_async && dio->rw == READ) { 466 if (dio->is_async && dio->rw == READ) {
@@ -476,7 +475,7 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio)
476 } 475 }
477 bio_put(bio); 476 bio_put(bio);
478 } 477 }
479 return uptodate ? 0 : -EIO; 478 return bio->bi_error;
480} 479}
481 480
482/* 481/*