aboutsummaryrefslogtreecommitdiffstats
path: root/block/bio-integrity.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-integrity.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-integrity.c')
-rw-r--r--block/bio-integrity.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 719b7152aed1..4aecca79374a 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -355,13 +355,12 @@ static void bio_integrity_verify_fn(struct work_struct *work)
355 container_of(work, struct bio_integrity_payload, bip_work); 355 container_of(work, struct bio_integrity_payload, bip_work);
356 struct bio *bio = bip->bip_bio; 356 struct bio *bio = bip->bip_bio;
357 struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); 357 struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
358 int error;
359 358
360 error = bio_integrity_process(bio, bi->verify_fn); 359 bio->bi_error = bio_integrity_process(bio, bi->verify_fn);
361 360
362 /* Restore original bio completion handler */ 361 /* Restore original bio completion handler */
363 bio->bi_end_io = bip->bip_end_io; 362 bio->bi_end_io = bip->bip_end_io;
364 bio_endio(bio, error); 363 bio_endio(bio);
365} 364}
366 365
367/** 366/**
@@ -376,7 +375,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)
376 * in process context. This function postpones completion 375 * in process context. This function postpones completion
377 * accordingly. 376 * accordingly.
378 */ 377 */
379void bio_integrity_endio(struct bio *bio, int error) 378void bio_integrity_endio(struct bio *bio)
380{ 379{
381 struct bio_integrity_payload *bip = bio_integrity(bio); 380 struct bio_integrity_payload *bip = bio_integrity(bio);
382 381
@@ -386,9 +385,9 @@ void bio_integrity_endio(struct bio *bio, int error)
386 * integrity metadata. Restore original bio end_io handler 385 * integrity metadata. Restore original bio end_io handler
387 * and run it. 386 * and run it.
388 */ 387 */
389 if (error) { 388 if (bio->bi_error) {
390 bio->bi_end_io = bip->bip_end_io; 389 bio->bi_end_io = bip->bip_end_io;
391 bio_endio(bio, error); 390 bio_endio(bio);
392 391
393 return; 392 return;
394 } 393 }