Commit 7d690c15 authored by Al Viro's avatar Al Viro

iter_to_pipe(): switch to advancing variant of iov_iter_get_pages()

... and untangle the cleanup on failure to add into pipe.
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 480cb846
...@@ -1158,39 +1158,40 @@ static int iter_to_pipe(struct iov_iter *from, ...@@ -1158,39 +1158,40 @@ static int iter_to_pipe(struct iov_iter *from,
}; };
size_t total = 0; size_t total = 0;
int ret = 0; int ret = 0;
bool failed = false;
while (iov_iter_count(from) && !failed) { while (iov_iter_count(from)) {
struct page *pages[16]; struct page *pages[16];
ssize_t copied; ssize_t left;
size_t start; size_t start;
int n; int i, n;
copied = iov_iter_get_pages(from, pages, ~0UL, 16, &start); left = iov_iter_get_pages2(from, pages, ~0UL, 16, &start);
if (copied <= 0) { if (left <= 0) {
ret = copied; ret = left;
break; break;
} }
for (n = 0; copied; n++, start = 0) { n = DIV_ROUND_UP(left + start, PAGE_SIZE);
int size = min_t(int, copied, PAGE_SIZE - start); for (i = 0; i < n; i++) {
if (!failed) { int size = min_t(int, left, PAGE_SIZE - start);
buf.page = pages[n];
buf.offset = start; buf.page = pages[i];
buf.len = size; buf.offset = start;
ret = add_to_pipe(pipe, &buf); buf.len = size;
if (unlikely(ret < 0)) { ret = add_to_pipe(pipe, &buf);
failed = true; if (unlikely(ret < 0)) {
} else { iov_iter_revert(from, left);
iov_iter_advance(from, ret); // this one got dropped by add_to_pipe()
total += ret; while (++i < n)
} put_page(pages[i]);
} else { goto out;
put_page(pages[n]);
} }
copied -= size; total += ret;
left -= size;
start = 0;
} }
} }
out:
return total ? total : ret; return total ? total : ret;
} }
......
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