aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2009-01-04 02:43:38 -0500
committerJens Axboe <jens.axboe@oracle.com>2009-01-30 06:34:36 -0500
commit7b24fc4d7eb611da367dea3aad45473050aacd6c (patch)
tree42c42a317c2236c45edf523ea0fc527189a5203d
parentf2257b70b0f9b2fe8f2afd83fc6798dca75930b8 (diff)
block: Don't verify integrity metadata on read error
If we get an I/O error on a read request there is no point in doing a verify pass on the integrity buffer. Adjust the completion path accordingly. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--fs/bio-integrity.c25
-rw-r--r--include/linux/bio.h1
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 */