Commit 8f4e80da authored by Ming Lei's avatar Ming Lei Committed by Jens Axboe

block: bounce: make sure that bvec table is updated

Block bounce needs to allocate new page for doing IO, and the
new page has to be updated to bvec table.

Commit 6dc4f100 switches __blk_queue_bounce() to use the new
bio_for_each_segment_all() interface. Unfortunately the new
bio_for_each_segment_all() can't be used to update bvec table.

This patch fixes this issue by retrieving bvec from the table
directly, then the new allocated page can be updated to the bio.
This way is safe because the cloned bio is single page bvec.

Fixes: 6dc4f100 ("block: allow bio_for_each_segment_all() to iterate over multi-page bvec")
Cc: Christoph Hellwig <hch@lst.de>
Cc: Omar Sandoval <osandov@fb.com>
Signed-off-by: default avatarMing Lei <ming.lei@redhat.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 037b2625
...@@ -295,7 +295,6 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig, ...@@ -295,7 +295,6 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
bool bounce = false; bool bounce = false;
int sectors = 0; int sectors = 0;
bool passthrough = bio_is_passthrough(*bio_orig); bool passthrough = bio_is_passthrough(*bio_orig);
struct bvec_iter_all iter_all;
bio_for_each_segment(from, *bio_orig, iter) { bio_for_each_segment(from, *bio_orig, iter) {
if (i++ < BIO_MAX_PAGES) if (i++ < BIO_MAX_PAGES)
...@@ -315,7 +314,12 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig, ...@@ -315,7 +314,12 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
bio = bounce_clone_bio(*bio_orig, GFP_NOIO, passthrough ? NULL : bio = bounce_clone_bio(*bio_orig, GFP_NOIO, passthrough ? NULL :
&bounce_bio_set); &bounce_bio_set);
bio_for_each_segment_all(to, bio, i, iter_all) { /*
* Bvec table can't be updated by bio_for_each_segment_all(),
* so retrieve bvec from the table directly. This way is safe
* because the 'bio' is single-page bvec.
*/
for (i = 0, to = bio->bi_io_vec; i < bio->bi_vcnt; to++, i++) {
struct page *page = to->bv_page; struct page *page = to->bv_page;
if (page_to_pfn(page) <= q->limits.bounce_pfn) if (page_to_pfn(page) <= q->limits.bounce_pfn)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment