From: Al Viro Date: Thu, 9 Jun 2022 15:07:52 +0000 (-0400) Subject: iter_to_pipe(): switch to advancing variant of iov_iter_get_pages() X-Git-Tag: v6.6.17~6830^2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7d690c157c58d22de9ad71ef5c4e1f43cd8ad0e7;p=platform%2Fkernel%2Flinux-rpi.git iter_to_pipe(): switch to advancing variant of iov_iter_get_pages() ... and untangle the cleanup on failure to add into pipe. Reviewed-by: Jeff Layton Signed-off-by: Al Viro --- diff --git a/fs/splice.c b/fs/splice.c index 8772905..0878b85 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1158,39 +1158,40 @@ static int iter_to_pipe(struct iov_iter *from, }; size_t total = 0; int ret = 0; - bool failed = false; - while (iov_iter_count(from) && !failed) { + while (iov_iter_count(from)) { struct page *pages[16]; - ssize_t copied; + ssize_t left; size_t start; - int n; + int i, n; - copied = iov_iter_get_pages(from, pages, ~0UL, 16, &start); - if (copied <= 0) { - ret = copied; + left = iov_iter_get_pages2(from, pages, ~0UL, 16, &start); + if (left <= 0) { + ret = left; break; } - for (n = 0; copied; n++, start = 0) { - int size = min_t(int, copied, PAGE_SIZE - start); - if (!failed) { - buf.page = pages[n]; - buf.offset = start; - buf.len = size; - ret = add_to_pipe(pipe, &buf); - if (unlikely(ret < 0)) { - failed = true; - } else { - iov_iter_advance(from, ret); - total += ret; - } - } else { - put_page(pages[n]); + n = DIV_ROUND_UP(left + start, PAGE_SIZE); + for (i = 0; i < n; i++) { + int size = min_t(int, left, PAGE_SIZE - start); + + buf.page = pages[i]; + buf.offset = start; + buf.len = size; + ret = add_to_pipe(pipe, &buf); + if (unlikely(ret < 0)) { + iov_iter_revert(from, left); + // this one got dropped by add_to_pipe() + while (++i < n) + put_page(pages[i]); + goto out; } - copied -= size; + total += ret; + left -= size; + start = 0; } } +out: return total ? total : ret; }