bio_copy_user_iov(): saner bio size calculation

it's a bounce buffer; we don't *care* how badly is the real
source/destination fragmented, all that matters is the total
size.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2017-09-24 13:09:18 -04:00
parent 0a0f151364
commit d16d44ebb0

View File

@ -1201,33 +1201,11 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
struct bio_map_data *bmd;
struct page *page;
struct bio *bio;
int i, ret;
int nr_pages = 0;
int i = 0, ret;
int nr_pages;
unsigned int len = iter->count;
unsigned int offset = map_data ? offset_in_page(map_data->offset) : 0;
for (i = 0; i < iter->nr_segs; i++) {
unsigned long uaddr;
unsigned long end;
unsigned long start;
uaddr = (unsigned long) iter->iov[i].iov_base;
end = (uaddr + iter->iov[i].iov_len + PAGE_SIZE - 1)
>> PAGE_SHIFT;
start = uaddr >> PAGE_SHIFT;
/*
* Overflow, abort
*/
if (end < start)
return ERR_PTR(-EINVAL);
nr_pages += end - start;
}
if (offset)
nr_pages++;
bmd = bio_alloc_map_data(iter->nr_segs, gfp_mask);
if (!bmd)
return ERR_PTR(-ENOMEM);
@ -1242,6 +1220,10 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
bmd->iter = *iter;
bmd->iter.iov = bmd->iov;
nr_pages = DIV_ROUND_UP(offset + len, PAGE_SIZE);
if (nr_pages > BIO_MAX_PAGES)
nr_pages = BIO_MAX_PAGES;
ret = -ENOMEM;
bio = bio_kmalloc(gfp_mask, nr_pages);
if (!bio)