diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2017-06-29 14:31:15 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-07-03 18:56:29 -0400 |
commit | 63573e359d052e506d305c263576499f06355985 (patch) | |
tree | d7aa2bcea3e447cce87ab40611e2055a4d628622 /block/bio-integrity.c | |
parent | f9df1cd99ebd82f05e8f5e0aa7e38cb8d3c791d7 (diff) |
bio-integrity: Restore original iterator on verify stage
Currently ->verify_fn not woks at all because at the moment it is called
bio->bi_iter.bi_size == 0, so we do not iterate integrity bvecs at all.
In order to perform verification we need to know original data vector,
with new bvec rewind API this is trivial.
testcase: https://github.com/dmonakhov/xfstests/commit/3c6509eaa83b9c17cd0bc95d73fcdd76e1c54a85
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
[hch: adopted for new status values]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/bio-integrity.c')
-rw-r--r-- | block/bio-integrity.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 44c4c52681c2..8df4eb103ba9 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c | |||
@@ -184,10 +184,11 @@ static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi, | |||
184 | /** | 184 | /** |
185 | * bio_integrity_process - Process integrity metadata for a bio | 185 | * bio_integrity_process - Process integrity metadata for a bio |
186 | * @bio: bio to generate/verify integrity metadata for | 186 | * @bio: bio to generate/verify integrity metadata for |
187 | * @proc_iter: iterator to process | ||
187 | * @proc_fn: Pointer to the relevant processing function | 188 | * @proc_fn: Pointer to the relevant processing function |
188 | */ | 189 | */ |
189 | static blk_status_t bio_integrity_process(struct bio *bio, | 190 | static blk_status_t bio_integrity_process(struct bio *bio, |
190 | integrity_processing_fn *proc_fn) | 191 | struct bvec_iter *proc_iter, integrity_processing_fn *proc_fn) |
191 | { | 192 | { |
192 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | 193 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); |
193 | struct blk_integrity_iter iter; | 194 | struct blk_integrity_iter iter; |
@@ -200,10 +201,10 @@ static blk_status_t bio_integrity_process(struct bio *bio, | |||
200 | 201 | ||
201 | iter.disk_name = bio->bi_bdev->bd_disk->disk_name; | 202 | iter.disk_name = bio->bi_bdev->bd_disk->disk_name; |
202 | iter.interval = 1 << bi->interval_exp; | 203 | iter.interval = 1 << bi->interval_exp; |
203 | iter.seed = bip_get_seed(bip); | 204 | iter.seed = proc_iter->bi_sector; |
204 | iter.prot_buf = prot_buf; | 205 | iter.prot_buf = prot_buf; |
205 | 206 | ||
206 | bio_for_each_segment(bv, bio, bviter) { | 207 | __bio_for_each_segment(bv, bio, bviter, *proc_iter) { |
207 | void *kaddr = kmap_atomic(bv.bv_page); | 208 | void *kaddr = kmap_atomic(bv.bv_page); |
208 | 209 | ||
209 | iter.data_buf = kaddr + bv.bv_offset; | 210 | iter.data_buf = kaddr + bv.bv_offset; |
@@ -332,8 +333,10 @@ bool bio_integrity_prep(struct bio *bio) | |||
332 | } | 333 | } |
333 | 334 | ||
334 | /* Auto-generate integrity metadata if this is a write */ | 335 | /* Auto-generate integrity metadata if this is a write */ |
335 | if (bio_data_dir(bio) == WRITE) | 336 | if (bio_data_dir(bio) == WRITE) { |
336 | bio_integrity_process(bio, bi->profile->generate_fn); | 337 | bio_integrity_process(bio, &bio->bi_iter, |
338 | bi->profile->generate_fn); | ||
339 | } | ||
337 | return true; | 340 | return true; |
338 | 341 | ||
339 | err_end_io: | 342 | err_end_io: |
@@ -358,8 +361,19 @@ static void bio_integrity_verify_fn(struct work_struct *work) | |||
358 | container_of(work, struct bio_integrity_payload, bip_work); | 361 | container_of(work, struct bio_integrity_payload, bip_work); |
359 | struct bio *bio = bip->bip_bio; | 362 | struct bio *bio = bip->bip_bio; |
360 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | 363 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); |
364 | struct bvec_iter iter = bio->bi_iter; | ||
361 | 365 | ||
362 | bio->bi_status = bio_integrity_process(bio, bi->profile->verify_fn); | 366 | /* |
367 | * At the moment verify is called bio's iterator was advanced | ||
368 | * during split and completion, we need to rewind iterator to | ||
369 | * it's original position. | ||
370 | */ | ||
371 | if (bio_rewind_iter(bio, &iter, iter.bi_done)) { | ||
372 | bio->bi_status = bio_integrity_process(bio, &iter, | ||
373 | bi->profile->verify_fn); | ||
374 | } else { | ||
375 | bio->bi_status = BLK_STS_IOERR; | ||
376 | } | ||
363 | 377 | ||
364 | /* Restore original bio completion handler */ | 378 | /* Restore original bio completion handler */ |
365 | bio->bi_end_io = bip->bip_end_io; | 379 | bio->bi_end_io = bip->bip_end_io; |