iov_iter: massage calling conventions for first_{iovec,bvec}_segment()
Pass maxsize by reference, return length via the same. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
dda8e5d17c
Коммит
59dbd7d090
|
@ -1294,8 +1294,7 @@ static ssize_t iter_xarray_get_pages(struct iov_iter *i,
|
||||||
|
|
||||||
/* must be done on non-empty ITER_IOVEC one */
|
/* must be done on non-empty ITER_IOVEC one */
|
||||||
static unsigned long first_iovec_segment(const struct iov_iter *i,
|
static unsigned long first_iovec_segment(const struct iov_iter *i,
|
||||||
size_t *size, size_t *start,
|
size_t *size, size_t *start)
|
||||||
size_t maxsize)
|
|
||||||
{
|
{
|
||||||
size_t skip;
|
size_t skip;
|
||||||
long k;
|
long k;
|
||||||
|
@ -1306,10 +1305,9 @@ static unsigned long first_iovec_segment(const struct iov_iter *i,
|
||||||
|
|
||||||
if (unlikely(!len))
|
if (unlikely(!len))
|
||||||
continue;
|
continue;
|
||||||
if (len > maxsize)
|
if (*size > len)
|
||||||
len = maxsize;
|
*size = len;
|
||||||
*start = addr % PAGE_SIZE;
|
*start = addr % PAGE_SIZE;
|
||||||
*size = len;
|
|
||||||
return addr & PAGE_MASK;
|
return addr & PAGE_MASK;
|
||||||
}
|
}
|
||||||
BUG(); // if it had been empty, we wouldn't get called
|
BUG(); // if it had been empty, we wouldn't get called
|
||||||
|
@ -1317,19 +1315,17 @@ static unsigned long first_iovec_segment(const struct iov_iter *i,
|
||||||
|
|
||||||
/* must be done on non-empty ITER_BVEC one */
|
/* must be done on non-empty ITER_BVEC one */
|
||||||
static struct page *first_bvec_segment(const struct iov_iter *i,
|
static struct page *first_bvec_segment(const struct iov_iter *i,
|
||||||
size_t *size, size_t *start,
|
size_t *size, size_t *start)
|
||||||
size_t maxsize)
|
|
||||||
{
|
{
|
||||||
struct page *page;
|
struct page *page;
|
||||||
size_t skip = i->iov_offset, len;
|
size_t skip = i->iov_offset, len;
|
||||||
|
|
||||||
len = i->bvec->bv_len - skip;
|
len = i->bvec->bv_len - skip;
|
||||||
if (len > maxsize)
|
if (*size > len)
|
||||||
len = maxsize;
|
*size = len;
|
||||||
skip += i->bvec->bv_offset;
|
skip += i->bvec->bv_offset;
|
||||||
page = i->bvec->bv_page + skip / PAGE_SIZE;
|
page = i->bvec->bv_page + skip / PAGE_SIZE;
|
||||||
*start = skip % PAGE_SIZE;
|
*start = skip % PAGE_SIZE;
|
||||||
*size = len;
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1337,7 +1333,6 @@ ssize_t iov_iter_get_pages(struct iov_iter *i,
|
||||||
struct page **pages, size_t maxsize, unsigned maxpages,
|
struct page **pages, size_t maxsize, unsigned maxpages,
|
||||||
size_t *start)
|
size_t *start)
|
||||||
{
|
{
|
||||||
size_t len;
|
|
||||||
int n, res;
|
int n, res;
|
||||||
|
|
||||||
if (maxsize > i->count)
|
if (maxsize > i->count)
|
||||||
|
@ -1356,25 +1351,25 @@ ssize_t iov_iter_get_pages(struct iov_iter *i,
|
||||||
if (i->nofault)
|
if (i->nofault)
|
||||||
gup_flags |= FOLL_NOFAULT;
|
gup_flags |= FOLL_NOFAULT;
|
||||||
|
|
||||||
addr = first_iovec_segment(i, &len, start, maxsize);
|
addr = first_iovec_segment(i, &maxsize, start);
|
||||||
n = DIV_ROUND_UP(len + *start, PAGE_SIZE);
|
n = DIV_ROUND_UP(maxsize + *start, PAGE_SIZE);
|
||||||
if (n > maxpages)
|
if (n > maxpages)
|
||||||
n = maxpages;
|
n = maxpages;
|
||||||
res = get_user_pages_fast(addr, n, gup_flags, pages);
|
res = get_user_pages_fast(addr, n, gup_flags, pages);
|
||||||
if (unlikely(res <= 0))
|
if (unlikely(res <= 0))
|
||||||
return res;
|
return res;
|
||||||
return min_t(size_t, len, res * PAGE_SIZE - *start);
|
return min_t(size_t, maxsize, res * PAGE_SIZE - *start);
|
||||||
}
|
}
|
||||||
if (iov_iter_is_bvec(i)) {
|
if (iov_iter_is_bvec(i)) {
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
|
||||||
page = first_bvec_segment(i, &len, start, maxsize);
|
page = first_bvec_segment(i, &maxsize, start);
|
||||||
n = DIV_ROUND_UP(len + *start, PAGE_SIZE);
|
n = DIV_ROUND_UP(maxsize + *start, PAGE_SIZE);
|
||||||
if (n > maxpages)
|
if (n > maxpages)
|
||||||
n = maxpages;
|
n = maxpages;
|
||||||
for (int k = 0; k < n; k++)
|
for (int k = 0; k < n; k++)
|
||||||
get_page(*pages++ = page++);
|
get_page(*pages++ = page++);
|
||||||
return min_t(size_t, len, n * PAGE_SIZE - *start);
|
return min_t(size_t, maxsize, n * PAGE_SIZE - *start);
|
||||||
}
|
}
|
||||||
if (iov_iter_is_pipe(i))
|
if (iov_iter_is_pipe(i))
|
||||||
return pipe_get_pages(i, pages, maxsize, maxpages, start);
|
return pipe_get_pages(i, pages, maxsize, maxpages, start);
|
||||||
|
@ -1469,7 +1464,6 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
|
||||||
size_t *start)
|
size_t *start)
|
||||||
{
|
{
|
||||||
struct page **p;
|
struct page **p;
|
||||||
size_t len;
|
|
||||||
int n, res;
|
int n, res;
|
||||||
|
|
||||||
if (maxsize > i->count)
|
if (maxsize > i->count)
|
||||||
|
@ -1488,8 +1482,8 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
|
||||||
if (i->nofault)
|
if (i->nofault)
|
||||||
gup_flags |= FOLL_NOFAULT;
|
gup_flags |= FOLL_NOFAULT;
|
||||||
|
|
||||||
addr = first_iovec_segment(i, &len, start, maxsize);
|
addr = first_iovec_segment(i, &maxsize, start);
|
||||||
n = DIV_ROUND_UP(len + *start, PAGE_SIZE);
|
n = DIV_ROUND_UP(maxsize + *start, PAGE_SIZE);
|
||||||
p = get_pages_array(n);
|
p = get_pages_array(n);
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1500,19 +1494,19 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
*pages = p;
|
*pages = p;
|
||||||
return min_t(size_t, len, res * PAGE_SIZE - *start);
|
return min_t(size_t, maxsize, res * PAGE_SIZE - *start);
|
||||||
}
|
}
|
||||||
if (iov_iter_is_bvec(i)) {
|
if (iov_iter_is_bvec(i)) {
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
|
||||||
page = first_bvec_segment(i, &len, start, maxsize);
|
page = first_bvec_segment(i, &maxsize, start);
|
||||||
n = DIV_ROUND_UP(len + *start, PAGE_SIZE);
|
n = DIV_ROUND_UP(maxsize + *start, PAGE_SIZE);
|
||||||
*pages = p = get_pages_array(n);
|
*pages = p = get_pages_array(n);
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
for (int k = 0; k < n; k++)
|
for (int k = 0; k < n; k++)
|
||||||
get_page(*p++ = page++);
|
get_page(*p++ = page++);
|
||||||
return min_t(size_t, len, n * PAGE_SIZE - *start);
|
return min_t(size_t, maxsize, n * PAGE_SIZE - *start);
|
||||||
}
|
}
|
||||||
if (iov_iter_is_pipe(i))
|
if (iov_iter_is_pipe(i))
|
||||||
return pipe_get_pages_alloc(i, pages, maxsize, start);
|
return pipe_get_pages_alloc(i, pages, maxsize, start);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче