diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2025-04-09 16:35:41 +1000 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2025-04-09 22:57:27 +0200 |
commit | 6693fa115824d198b7cde46c272514be194500a9 (patch) | |
tree | 300ee02b57eb2c88c1d88b1b8af9643dc538c3d3 | |
parent | d3f33f3b8ec4646dae3584b648cba142a73d3208 (diff) | |
download | passt-6693fa115824d198b7cde46c272514be194500a9.tar passt-6693fa115824d198b7cde46c272514be194500a9.tar.gz passt-6693fa115824d198b7cde46c272514be194500a9.tar.bz2 passt-6693fa115824d198b7cde46c272514be194500a9.tar.lz passt-6693fa115824d198b7cde46c272514be194500a9.tar.xz passt-6693fa115824d198b7cde46c272514be194500a9.tar.zst passt-6693fa115824d198b7cde46c272514be194500a9.zip |
tcp_splice: Don't clobber errno before checking for EAGAIN
Like many places, tcp_splice_sock_handler() needs to handle EAGAIN
specially, in this case for both of its splice() calls. Unfortunately it
tests for EAGAIN some time after those calls. In between there has been
at least a flow_trace() which could have clobbered errno. Move the test on
errno closer to the relevant system calls to avoid this problem.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r-- | tcp_splice.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/tcp_splice.c b/tcp_splice.c index 7c3b56f..60455d6 100644 --- a/tcp_splice.c +++ b/tcp_splice.c @@ -526,13 +526,15 @@ retry: c->tcp.pipe_size, SPLICE_F_MOVE | SPLICE_F_NONBLOCK); while (readlen < 0 && errno == EINTR); + + if (readlen < 0 && errno != EAGAIN) + goto close; + flow_trace(conn, "%zi from read-side call", readlen); - if (readlen < 0) { - if (errno != EAGAIN) - goto close; - } else if (!readlen) { + + if (!readlen) { eof = 1; - } else { + } else if (readlen > 0) { never_read = 0; if (readlen >= (long)c->tcp.pipe_size * 90 / 100) @@ -549,6 +551,9 @@ retry: SPLICE_F_MOVE | more | SPLICE_F_NONBLOCK); while (written < 0 && errno == EINTR); + if (written < 0 && errno != EAGAIN) + goto close; + flow_trace(conn, "%zi from write-side call (passed %zi)", written, c->tcp.pipe_size); @@ -580,9 +585,6 @@ retry: conn->written[fromsidei] += written > 0 ? written : 0; if (written < 0) { - if (errno != EAGAIN) - goto close; - if (conn->read[fromsidei] == conn->written[fromsidei]) break; |