diff options
-rw-r--r-- | fs/bio-integrity.c | 25 | ||||
-rw-r--r-- | include/linux/bio.h | 1 |
2 files changed, 15 insertions, 11 deletions
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c index 77ebc3c263d6..8396d741f804 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c | |||
@@ -465,7 +465,7 @@ static int bio_integrity_verify(struct bio *bio) | |||
465 | 465 | ||
466 | if (ret) { | 466 | if (ret) { |
467 | kunmap_atomic(kaddr, KM_USER0); | 467 | kunmap_atomic(kaddr, KM_USER0); |
468 | break; | 468 | return ret; |
469 | } | 469 | } |
470 | 470 | ||
471 | sectors = bv->bv_len / bi->sector_size; | 471 | sectors = bv->bv_len / bi->sector_size; |
@@ -493,18 +493,13 @@ static void bio_integrity_verify_fn(struct work_struct *work) | |||
493 | struct bio_integrity_payload *bip = | 493 | struct bio_integrity_payload *bip = |
494 | container_of(work, struct bio_integrity_payload, bip_work); | 494 | container_of(work, struct bio_integrity_payload, bip_work); |
495 | struct bio *bio = bip->bip_bio; | 495 | struct bio *bio = bip->bip_bio; |
496 | int error = bip->bip_error; | 496 | int error; |
497 | 497 | ||
498 | if (bio_integrity_verify(bio)) { | 498 | error = bio_integrity_verify(bio); |
499 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | ||
500 | error = -EIO; | ||
501 | } | ||
502 | 499 | ||
503 | /* Restore original bio completion handler */ | 500 | /* Restore original bio completion handler */ |
504 | bio->bi_end_io = bip->bip_end_io; | 501 | bio->bi_end_io = bip->bip_end_io; |
505 | 502 | bio_endio(bio, error); | |
506 | if (bio->bi_end_io) | ||
507 | bio->bi_end_io(bio, error); | ||
508 | } | 503 | } |
509 | 504 | ||
510 | /** | 505 | /** |
@@ -525,7 +520,17 @@ void bio_integrity_endio(struct bio *bio, int error) | |||
525 | 520 | ||
526 | BUG_ON(bip->bip_bio != bio); | 521 | BUG_ON(bip->bip_bio != bio); |
527 | 522 | ||
528 | bip->bip_error = error; | 523 | /* In case of an I/O error there is no point in verifying the |
524 | * integrity metadata. Restore original bio end_io handler | ||
525 | * and run it. | ||
526 | */ | ||
527 | if (error) { | ||
528 | bio->bi_end_io = bip->bip_end_io; | ||
529 | bio_endio(bio, error); | ||
530 | |||
531 | return; | ||
532 | } | ||
533 | |||
529 | INIT_WORK(&bip->bip_work, bio_integrity_verify_fn); | 534 | INIT_WORK(&bip->bip_work, bio_integrity_verify_fn); |
530 | queue_work(kintegrityd_wq, &bip->bip_work); | 535 | queue_work(kintegrityd_wq, &bip->bip_work); |
531 | } | 536 | } |
diff --git a/include/linux/bio.h b/include/linux/bio.h index 18462c5b8fff..18fc4a281a7b 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -312,7 +312,6 @@ struct bio_integrity_payload { | |||
312 | void *bip_buf; /* generated integrity data */ | 312 | void *bip_buf; /* generated integrity data */ |
313 | bio_end_io_t *bip_end_io; /* saved I/O completion fn */ | 313 | bio_end_io_t *bip_end_io; /* saved I/O completion fn */ |
314 | 314 | ||
315 | int bip_error; /* saved I/O error */ | ||
316 | unsigned int bip_size; | 315 | unsigned int bip_size; |
317 | 316 | ||
318 | unsigned short bip_pool; /* pool the ivec came from */ | 317 | unsigned short bip_pool; /* pool the ivec came from */ |