Loading fs/splice.c +24 −23 Original line number Original line Diff line number Diff line Loading @@ -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.page = pages[i]; buf.offset = start; buf.offset = start; buf.len = size; buf.len = size; ret = add_to_pipe(pipe, &buf); ret = add_to_pipe(pipe, &buf); if (unlikely(ret < 0)) { if (unlikely(ret < 0)) { failed = true; iov_iter_revert(from, left); } else { // this one got dropped by add_to_pipe() iov_iter_advance(from, ret); while (++i < n) total += ret; put_page(pages[i]); } goto out; } else { put_page(pages[n]); } } copied -= size; total += ret; left -= size; start = 0; } } } } out: return total ? total : ret; return total ? total : ret; } } Loading Loading
fs/splice.c +24 −23 Original line number Original line Diff line number Diff line Loading @@ -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.page = pages[i]; buf.offset = start; buf.offset = start; buf.len = size; buf.len = size; ret = add_to_pipe(pipe, &buf); ret = add_to_pipe(pipe, &buf); if (unlikely(ret < 0)) { if (unlikely(ret < 0)) { failed = true; iov_iter_revert(from, left); } else { // this one got dropped by add_to_pipe() iov_iter_advance(from, ret); while (++i < n) total += ret; put_page(pages[i]); } goto out; } else { put_page(pages[n]); } } copied -= size; total += ret; left -= size; start = 0; } } } } out: return total ? total : ret; return total ? total : ret; } } Loading