Message ID | 1428985.1686737388@warthog.procyon.org.uk (mailing list archive) |
---|---|
State | Accepted |
Commit | ca2d49f77ce4531c74ba207b1e07b55f5ced5ab4 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net-next] splice, net: Fix splice_to_socket() to handle pipe bufs larger than a page | expand |
Hello: This patch was applied to netdev/net-next.git (main) by Jakub Kicinski <kuba@kernel.org>: On Wed, 14 Jun 2023 11:09:48 +0100 you wrote: > splice_to_socket() assumes that a pipe_buffer won't hold more than a single > page of data - but this assumption can be violated by skb_splice_bits() > when it splices from a socket into a pipe. > > The problem is that splice_to_socket() doesn't advance the pipe_buffer > length and offset when transcribing from the pipe buf into a bio_vec, so if > the buf is >PAGE_SIZE, it keeps repeating the same initial chunk and > doesn't advance the tail index. It then subtracts this from "remain" and > overcounts the amount of data to be sent. > > [...] Here is the summary with links: - [net-next] splice, net: Fix splice_to_socket() to handle pipe bufs larger than a page https://git.kernel.org/netdev/net-next/c/ca2d49f77ce4 You are awesome, thank you!
diff --git a/fs/splice.c b/fs/splice.c index e337630aed64..567a1f03ea1e 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -886,7 +886,6 @@ ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, } seg = min_t(size_t, remain, buf->len); - seg = min_t(size_t, seg, PAGE_SIZE); ret = pipe_buf_confirm(pipe, buf); if (unlikely(ret)) { @@ -897,10 +896,9 @@ ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, bvec_set_page(&bvec[bc++], buf->page, seg, buf->offset); remain -= seg; - if (seg >= buf->len) - tail++; - if (bc >= ARRAY_SIZE(bvec)) + if (remain == 0 || bc >= ARRAY_SIZE(bvec)) break; + tail++; } if (!bc)