Split iov_iter_get_pages() by type. Signed-off-by: David Howells <dhowells@xxxxxxxxxx> --- lib/iov_iter.c | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 5744ddec854f..a2de201b947f 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -1611,6 +1611,8 @@ static ssize_t pipe_get_pages(struct iov_iter *i, unsigned int iter_head, npages; size_t capacity; + if (maxsize > i->count) + maxsize = i->count; if (!maxsize) return 0; @@ -1625,19 +1627,14 @@ static ssize_t pipe_get_pages(struct iov_iter *i, return __pipe_get_pages(i, min(maxsize, capacity), pages, iter_head, start); } -static ssize_t xxx_get_pages(struct iov_iter *i, +static ssize_t iovec_get_pages(struct iov_iter *i, struct page **pages, size_t maxsize, unsigned maxpages, size_t *start) { if (maxsize > i->count) maxsize = i->count; - if (unlikely(iov_iter_is_pipe(i))) - return pipe_get_pages(i, pages, maxsize, maxpages, start); - if (unlikely(iov_iter_is_discard(i))) - return -EFAULT; - - iterate_all_kinds(i, maxsize, v, ({ + iterate_over_iovec(i, maxsize, v, ({ unsigned long addr = (unsigned long)v.iov_base; size_t len = v.iov_len + (*start = addr & (PAGE_SIZE - 1)); int n; @@ -1653,18 +1650,33 @@ static ssize_t xxx_get_pages(struct iov_iter *i, if (unlikely(res < 0)) return res; return (res == n ? len : res * PAGE_SIZE) - *start; - 0;}),({ + 0;})); + return 0; +} + +static ssize_t bvec_get_pages(struct iov_iter *i, + struct page **pages, size_t maxsize, unsigned maxpages, + size_t *start) +{ + if (maxsize > i->count) + maxsize = i->count; + + iterate_over_bvec(i, maxsize, v, ({ /* can't be more than PAGE_SIZE */ *start = v.bv_offset; get_page(*pages = v.bv_page); return v.bv_len; - }),({ - return -EFAULT; - }) - ) + })); return 0; } +static ssize_t no_get_pages(struct iov_iter *i, + struct page **pages, size_t maxsize, unsigned maxpages, + size_t *start) +{ + return -EFAULT; +} + static struct page **get_pages_array(size_t n) { return kvmalloc_array(n, sizeof(struct page *), GFP_KERNEL); @@ -2179,7 +2191,7 @@ static const struct iov_iter_ops iovec_iter_ops = { .zero = iovec_zero, .alignment = iovec_alignment, .gap_alignment = iovec_gap_alignment, - .get_pages = xxx_get_pages, + .get_pages = iovec_get_pages, .get_pages_alloc = xxx_get_pages_alloc, .npages = xxx_npages, .dup_iter = xxx_dup_iter, @@ -2213,7 +2225,7 @@ static const struct iov_iter_ops kvec_iter_ops = { .zero = kvec_zero, .alignment = kvec_alignment, .gap_alignment = kvec_gap_alignment, - .get_pages = xxx_get_pages, + .get_pages = no_get_pages, .get_pages_alloc = xxx_get_pages_alloc, .npages = xxx_npages, .dup_iter = xxx_dup_iter, @@ -2247,7 +2259,7 @@ static const struct iov_iter_ops bvec_iter_ops = { .zero = bvec_zero, .alignment = bvec_alignment, .gap_alignment = bvec_gap_alignment, - .get_pages = xxx_get_pages, + .get_pages = bvec_get_pages, .get_pages_alloc = xxx_get_pages_alloc, .npages = xxx_npages, .dup_iter = xxx_dup_iter, @@ -2281,7 +2293,7 @@ static const struct iov_iter_ops pipe_iter_ops = { .zero = pipe_zero, .alignment = pipe_alignment, .gap_alignment = no_gap_alignment, - .get_pages = xxx_get_pages, + .get_pages = pipe_get_pages, .get_pages_alloc = xxx_get_pages_alloc, .npages = xxx_npages, .dup_iter = xxx_dup_iter, @@ -2315,7 +2327,7 @@ static const struct iov_iter_ops discard_iter_ops = { .zero = discard_zero, .alignment = no_alignment, .gap_alignment = no_gap_alignment, - .get_pages = xxx_get_pages, + .get_pages = no_get_pages, .get_pages_alloc = xxx_get_pages_alloc, .npages = xxx_npages, .dup_iter = xxx_dup_iter,