diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2017-06-29 21:31:14 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-07-04 01:56:28 +0300 |
commit | f9df1cd99ebd82f05e8f5e0aa7e38cb8d3c791d7 (patch) | |
tree | b5d6222cd50a8e57719e6dbbb57dd5392a07096b /include/linux/bio.h | |
parent | b1fb2c52b2d85f51f36f1661409f9aeef94265ff (diff) | |
download | linux-f9df1cd99ebd82f05e8f5e0aa7e38cb8d3c791d7.tar.xz |
bio: add bvec_iter rewind API
Some ->bi_end_io handlers (for example: pi_verify or decrypt handlers)
need to know original data vector, but after bio traverse io-stack it may
be advanced, splited and relocated many times so it is hard to guess
original iterator. Let's add 'bi_done' conter which accounts number
of bytes iterator was advanced during it's evolution. Later end_io handler
may easily restore original iterator by rewinding iterator to
iter->bi_done.
Note: this change makes sizeof (struct bvec_iter) multiple to 8
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
[hch: switched to true/false return]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'include/linux/bio.h')
-rw-r--r-- | include/linux/bio.h | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h index d5e8689f86b8..1eba19580185 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -165,14 +165,29 @@ static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter, { iter->bi_sector += bytes >> 9; - if (bio_no_advance_iter(bio)) + if (bio_no_advance_iter(bio)) { iter->bi_size -= bytes; - else { + iter->bi_done += bytes; + } else { bvec_iter_advance(bio->bi_io_vec, iter, bytes); /* TODO: It is reasonable to complete bio with error here. */ } } +static inline bool bio_rewind_iter(struct bio *bio, struct bvec_iter *iter, + unsigned int bytes) +{ + iter->bi_sector -= bytes >> 9; + + if (bio_no_advance_iter(bio)) { + iter->bi_size += bytes; + iter->bi_done -= bytes; + return true; + } + + return bvec_iter_rewind(bio->bi_io_vec, iter, bytes); +} + #define __bio_for_each_segment(bvl, bio, iter, start) \ for (iter = (start); \ (iter).bi_size && \ |