Skip to content

Commit 63573e3

Browse files
Dmitry Monakhovaxboe
authored andcommitted
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: dmonakhov/xfstests@3c6509e Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Dmitry Monakhov <[email protected]> [hch: adopted for new status values] Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent f9df1cd commit 63573e3

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

block/bio-integrity.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,11 @@ static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
184184
/**
185185
* bio_integrity_process - Process integrity metadata for a bio
186186
* @bio: bio to generate/verify integrity metadata for
187+
* @proc_iter: iterator to process
187188
* @proc_fn: Pointer to the relevant processing function
188189
*/
189190
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)
191192
{
192193
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
193194
struct blk_integrity_iter iter;
@@ -200,10 +201,10 @@ static blk_status_t bio_integrity_process(struct bio *bio,
200201

201202
iter.disk_name = bio->bi_bdev->bd_disk->disk_name;
202203
iter.interval = 1 << bi->interval_exp;
203-
iter.seed = bip_get_seed(bip);
204+
iter.seed = proc_iter->bi_sector;
204205
iter.prot_buf = prot_buf;
205206

206-
bio_for_each_segment(bv, bio, bviter) {
207+
__bio_for_each_segment(bv, bio, bviter, *proc_iter) {
207208
void *kaddr = kmap_atomic(bv.bv_page);
208209

209210
iter.data_buf = kaddr + bv.bv_offset;
@@ -332,8 +333,10 @@ bool bio_integrity_prep(struct bio *bio)
332333
}
333334

334335
/* Auto-generate integrity metadata if this is a write */
335-
if (bio_data_dir(bio) == WRITE)
336-
bio_integrity_process(bio, bi->profile->generate_fn);
336+
if (bio_data_dir(bio) == WRITE) {
337+
bio_integrity_process(bio, &bio->bi_iter,
338+
bi->profile->generate_fn);
339+
}
337340
return true;
338341

339342
err_end_io:
@@ -358,8 +361,19 @@ static void bio_integrity_verify_fn(struct work_struct *work)
358361
container_of(work, struct bio_integrity_payload, bip_work);
359362
struct bio *bio = bip->bip_bio;
360363
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
364+
struct bvec_iter iter = bio->bi_iter;
361365

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+
}
363377

364378
/* Restore original bio completion handler */
365379
bio->bi_end_io = bip->bip_end_io;

0 commit comments

Comments
 (0)