diff options
author | Martin K. Petersen <martin.petersen@oracle.com> | 2009-01-04 02:43:38 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-01-30 12:34:36 +0100 |
commit | 7b24fc4d7eb611da367dea3aad45473050aacd6c (patch) | |
tree | 42c42a317c2236c45edf523ea0fc527189a5203d | |
parent | f2257b70b0f9b2fe8f2afd83fc6798dca75930b8 (diff) | |
download | op-kernel-dev-7b24fc4d7eb611da367dea3aad45473050aacd6c.zip op-kernel-dev-7b24fc4d7eb611da367dea3aad45473050aacd6c.tar.gz |
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.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 77ebc3c..8396d74 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c @@ -465,7 +465,7 @@ static int bio_integrity_verify(struct bio *bio) if (ret) { kunmap_atomic(kaddr, KM_USER0); - break; + return ret; } sectors = bv->bv_len / bi->sector_size; @@ -493,18 +493,13 @@ static void bio_integrity_verify_fn(struct work_struct *work) struct bio_integrity_payload *bip = container_of(work, struct bio_integrity_payload, bip_work); struct bio *bio = bip->bip_bio; - int error = bip->bip_error; + int error; - if (bio_integrity_verify(bio)) { - clear_bit(BIO_UPTODATE, &bio->bi_flags); - error = -EIO; - } + error = bio_integrity_verify(bio); /* Restore original bio completion handler */ bio->bi_end_io = bip->bip_end_io; - - if (bio->bi_end_io) - bio->bi_end_io(bio, error); + bio_endio(bio, error); } /** @@ -525,7 +520,17 @@ void bio_integrity_endio(struct bio *bio, int error) BUG_ON(bip->bip_bio != bio); - bip->bip_error = error; + /* In case of an I/O error there is no point in verifying the + * integrity metadata. Restore original bio end_io handler + * and run it. + */ + if (error) { + bio->bi_end_io = bip->bip_end_io; + bio_endio(bio, error); + + return; + } + INIT_WORK(&bip->bip_work, bio_integrity_verify_fn); queue_work(kintegrityd_wq, &bip->bip_work); } diff --git a/include/linux/bio.h b/include/linux/bio.h index 18462c5..18fc4a2 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -312,7 +312,6 @@ struct bio_integrity_payload { void *bip_buf; /* generated integrity data */ bio_end_io_t *bip_end_io; /* saved I/O completion fn */ - int bip_error; /* saved I/O error */ unsigned int bip_size; unsigned short bip_pool; /* pool the ivec came from */ |