diff options
Diffstat (limited to 'fs/bio-integrity.c')
-rw-r--r-- | fs/bio-integrity.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c index 77ebc3c263d6..fe2b1aa2464e 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c | |||
@@ -140,7 +140,6 @@ int bio_integrity_add_page(struct bio *bio, struct page *page, | |||
140 | 140 | ||
141 | iv = bip_vec_idx(bip, bip->bip_vcnt); | 141 | iv = bip_vec_idx(bip, bip->bip_vcnt); |
142 | BUG_ON(iv == NULL); | 142 | BUG_ON(iv == NULL); |
143 | BUG_ON(iv->bv_page != NULL); | ||
144 | 143 | ||
145 | iv->bv_page = page; | 144 | iv->bv_page = page; |
146 | iv->bv_len = len; | 145 | iv->bv_len = len; |
@@ -465,7 +464,7 @@ static int bio_integrity_verify(struct bio *bio) | |||
465 | 464 | ||
466 | if (ret) { | 465 | if (ret) { |
467 | kunmap_atomic(kaddr, KM_USER0); | 466 | kunmap_atomic(kaddr, KM_USER0); |
468 | break; | 467 | return ret; |
469 | } | 468 | } |
470 | 469 | ||
471 | sectors = bv->bv_len / bi->sector_size; | 470 | sectors = bv->bv_len / bi->sector_size; |
@@ -493,18 +492,13 @@ static void bio_integrity_verify_fn(struct work_struct *work) | |||
493 | struct bio_integrity_payload *bip = | 492 | struct bio_integrity_payload *bip = |
494 | container_of(work, struct bio_integrity_payload, bip_work); | 493 | container_of(work, struct bio_integrity_payload, bip_work); |
495 | struct bio *bio = bip->bip_bio; | 494 | struct bio *bio = bip->bip_bio; |
496 | int error = bip->bip_error; | 495 | int error; |
497 | 496 | ||
498 | if (bio_integrity_verify(bio)) { | 497 | error = bio_integrity_verify(bio); |
499 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | ||
500 | error = -EIO; | ||
501 | } | ||
502 | 498 | ||
503 | /* Restore original bio completion handler */ | 499 | /* Restore original bio completion handler */ |
504 | bio->bi_end_io = bip->bip_end_io; | 500 | bio->bi_end_io = bip->bip_end_io; |
505 | 501 | bio_endio(bio, error); | |
506 | if (bio->bi_end_io) | ||
507 | bio->bi_end_io(bio, error); | ||
508 | } | 502 | } |
509 | 503 | ||
510 | /** | 504 | /** |
@@ -525,7 +519,17 @@ void bio_integrity_endio(struct bio *bio, int error) | |||
525 | 519 | ||
526 | BUG_ON(bip->bip_bio != bio); | 520 | BUG_ON(bip->bip_bio != bio); |
527 | 521 | ||
528 | bip->bip_error = error; | 522 | /* In case of an I/O error there is no point in verifying the |
523 | * integrity metadata. Restore original bio end_io handler | ||
524 | * and run it. | ||
525 | */ | ||
526 | if (error) { | ||
527 | bio->bi_end_io = bip->bip_end_io; | ||
528 | bio_endio(bio, error); | ||
529 | |||
530 | return; | ||
531 | } | ||
532 | |||
529 | INIT_WORK(&bip->bip_work, bio_integrity_verify_fn); | 533 | INIT_WORK(&bip->bip_work, bio_integrity_verify_fn); |
530 | queue_work(kintegrityd_wq, &bip->bip_work); | 534 | queue_work(kintegrityd_wq, &bip->bip_work); |
531 | } | 535 | } |
@@ -681,19 +685,20 @@ EXPORT_SYMBOL(bio_integrity_split); | |||
681 | * bio_integrity_clone - Callback for cloning bios with integrity metadata | 685 | * bio_integrity_clone - Callback for cloning bios with integrity metadata |
682 | * @bio: New bio | 686 | * @bio: New bio |
683 | * @bio_src: Original bio | 687 | * @bio_src: Original bio |
688 | * @gfp_mask: Memory allocation mask | ||
684 | * @bs: bio_set to allocate bip from | 689 | * @bs: bio_set to allocate bip from |
685 | * | 690 | * |
686 | * Description: Called to allocate a bip when cloning a bio | 691 | * Description: Called to allocate a bip when cloning a bio |
687 | */ | 692 | */ |
688 | int bio_integrity_clone(struct bio *bio, struct bio *bio_src, | 693 | int bio_integrity_clone(struct bio *bio, struct bio *bio_src, |
689 | struct bio_set *bs) | 694 | gfp_t gfp_mask, struct bio_set *bs) |
690 | { | 695 | { |
691 | struct bio_integrity_payload *bip_src = bio_src->bi_integrity; | 696 | struct bio_integrity_payload *bip_src = bio_src->bi_integrity; |
692 | struct bio_integrity_payload *bip; | 697 | struct bio_integrity_payload *bip; |
693 | 698 | ||
694 | BUG_ON(bip_src == NULL); | 699 | BUG_ON(bip_src == NULL); |
695 | 700 | ||
696 | bip = bio_integrity_alloc_bioset(bio, GFP_NOIO, bip_src->bip_vcnt, bs); | 701 | bip = bio_integrity_alloc_bioset(bio, gfp_mask, bip_src->bip_vcnt, bs); |
697 | 702 | ||
698 | if (bip == NULL) | 703 | if (bip == NULL) |
699 | return -EIO; | 704 | return -EIO; |