[PATCH net] net/smc: do not credit bytes that splice() did not take

Hidayath Khan <[email protected]>
Newsgroups org.kernel.vger.linux-rdma,org.kernel.vger.linux-s390,org.kernel.vger.netdev
Message-ID <[email protected]>
smc_rx_recvmsg() offers a chunk of the RMB to splice_to_pipe() and then
credits the whole chunk regardless of what was taken.

splice_to_pipe() takes only what the pipe has room for. A short count and
a zero count are both non-negative, so both fall through as success: the
call returns more than it delivered, and the consumer cursor and
bytes_to_rcv are advanced by copylen rather than by what the reader
received. The skipped bytes are never handed to anyone.

A pipe that is not empty is enough to hit this; SPLICE_F_NONBLOCK on a
full pipe produces the zero case.

Account what splice_to_pipe() actually took, and stop there rather than
continuing to the second chunk of a wrapped read. When it took nothing,
return -EAGAIN instead of reporting a length that was not delivered.

Fixes: 9014db202cb7 ("smc: add support for splice()")
Cc: [email protected]
Reviewed-by: Sidraya Jayagond <[email protected]>
Signed-off-by: Hidayath Khan <[email protected]>
---
 net/smc/smc_rx.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c
index 5c9e4d8b57de..d951dbe8eec3 100644
--- a/net/smc/smc_rx.c
+++ b/net/smc/smc_rx.c
@@ -488,6 +488,24 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg,
 						read_done = -EFAULT;
 					goto out;
 				}
+				/* splice_to_pipe() takes only what the pipe
+				 * has room for, which may be less than was
+				 * offered, or nothing. Account what it took
+				 * and stop: crediting the whole chunk would
+				 * advance the consumer past data the reader
+				 * never received.
+				 */
+				if (!msg && rc < chunk_len) {
+					if (!rc) {
+						if (!read_done)
+							read_done = -EAGAIN;
+						goto out;
+					}
+					copylen = chunk_len_sum - chunk_len + rc;
+					read_remaining -= rc;
+					read_done += rc;
+					break;
+				}
 			}
 			read_remaining -= chunk_len;
 			read_done += chunk_len;

base-commit: d3083202a78cd0040be6a88953f728b0d3db1990
-- 
2.52.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.