summaryrefslogtreecommitdiffstats
path: root/block/bio-integrity.c
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2017-06-29 14:31:15 -0400
committerJens Axboe <axboe@kernel.dk>2017-07-03 18:56:29 -0400
commit63573e359d052e506d305c263576499f06355985 (patch)
treed7aa2bcea3e447cce87ab40611e2055a4d628622 /block/bio-integrity.c
parentf9df1cd99ebd82f05e8f5e0aa7e38cb8d3c791d7 (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.c26
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 */
189static blk_status_t bio_integrity_process(struct bio *bio, 190static 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
339err_end_io: 342err_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;