Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 <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>
  • Loading branch information
Dmitry Monakhov authored and axboe committed Jul 3, 2017
1 parent f9df1cd commit 63573e3
Showing 1 changed file with 20 additions and 6 deletions.
26 changes: 20 additions & 6 deletions block/bio-integrity.c
Expand Up @@ -184,10 +184,11 @@ static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
/**
* bio_integrity_process - Process integrity metadata for a bio
* @bio: bio to generate/verify integrity metadata for
* @proc_iter: iterator to process
* @proc_fn: Pointer to the relevant processing function
*/
static blk_status_t bio_integrity_process(struct bio *bio,
integrity_processing_fn *proc_fn)
struct bvec_iter *proc_iter, integrity_processing_fn *proc_fn)
{
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
struct blk_integrity_iter iter;
Expand All @@ -200,10 +201,10 @@ static blk_status_t bio_integrity_process(struct bio *bio,

iter.disk_name = bio->bi_bdev->bd_disk->disk_name;
iter.interval = 1 << bi->interval_exp;
iter.seed = bip_get_seed(bip);
iter.seed = proc_iter->bi_sector;
iter.prot_buf = prot_buf;

bio_for_each_segment(bv, bio, bviter) {
__bio_for_each_segment(bv, bio, bviter, *proc_iter) {
void *kaddr = kmap_atomic(bv.bv_page);

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

/* Auto-generate integrity metadata if this is a write */
if (bio_data_dir(bio) == WRITE)
bio_integrity_process(bio, bi->profile->generate_fn);
if (bio_data_dir(bio) == WRITE) {
bio_integrity_process(bio, &bio->bi_iter,
bi->profile->generate_fn);
}
return true;

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

bio->bi_status = bio_integrity_process(bio, bi->profile->verify_fn);
/*
* At the moment verify is called bio's iterator was advanced
* during split and completion, we need to rewind iterator to
* it's original position.
*/
if (bio_rewind_iter(bio, &iter, iter.bi_done)) {
bio->bi_status = bio_integrity_process(bio, &iter,
bi->profile->verify_fn);
} else {
bio->bi_status = BLK_STS_IOERR;
}

/* Restore original bio completion handler */
bio->bi_end_io = bip->bip_end_io;
Expand Down

0 comments on commit 63573e3

Please sign in to comment.