diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-09-23 22:23:18 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-10-11 23:23:39 +0200 |
commit | 98f0bc99055da5797fae0c35d3d18261d59df9ac (patch) | |
tree | e71e78487aa8efa7b5e1d077976e7903997bb287 /block | |
parent | don't rely upon subsequent bio_add_pc_page() calls failing (diff) | |
download | linux-98f0bc99055da5797fae0c35d3d18261d59df9ac.tar.xz linux-98f0bc99055da5797fae0c35d3d18261d59df9ac.zip |
bio_map_user_iov(): move alignment check into the main loop
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'block')
-rw-r--r-- | block/bio.c | 54 |
1 files changed, 27 insertions, 27 deletions
diff --git a/block/bio.c b/block/bio.c index fe40948d62af..d851f68727f1 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1344,11 +1344,6 @@ struct bio *bio_map_user_iov(struct request_queue *q, return ERR_PTR(-EINVAL); nr_pages += end - start; - /* - * buffer must be aligned to at least logical block size for now - */ - if (uaddr & queue_dma_alignment(q)) - return ERR_PTR(-EINVAL); } if (!nr_pages) @@ -1373,29 +1368,34 @@ struct bio *bio_map_user_iov(struct request_queue *q, npages = DIV_ROUND_UP(offs + bytes, PAGE_SIZE); - for (j = 0; j < npages; j++) { - unsigned int n = PAGE_SIZE - offs; - unsigned short prev_bi_vcnt = bio->bi_vcnt; - - if (n > bytes) - n = bytes; - - if (!bio_add_pc_page(q, bio, pages[j], n, offs)) - break; - - /* - * check if vector was merged with previous - * drop page reference if needed - */ - if (bio->bi_vcnt == prev_bi_vcnt) - put_page(pages[j]); - - added += n; - bytes -= n; - offs = 0; + if (unlikely(offs & queue_dma_alignment(q))) { + ret = -EINVAL; + j = 0; + } else { + for (j = 0; j < npages; j++) { + struct page *page = pages[j]; + unsigned int n = PAGE_SIZE - offs; + unsigned short prev_bi_vcnt = bio->bi_vcnt; + + if (n > bytes) + n = bytes; + + if (!bio_add_pc_page(q, bio, page, n, offs)) + break; + + /* + * check if vector was merged with previous + * drop page reference if needed + */ + if (bio->bi_vcnt == prev_bi_vcnt) + put_page(page); + + added += n; + bytes -= n; + offs = 0; + } + iov_iter_advance(&i, added); } - iov_iter_advance(&i, added); - /* * release the pages we didn't map into the bio, if any */ |