aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2025-04-09 16:35:41 +1000
committerStefano Brivio <sbrivio@redhat.com>2025-04-09 22:57:27 +0200
commit6693fa115824d198b7cde46c272514be194500a9 (patch)
tree300ee02b57eb2c88c1d88b1b8af9643dc538c3d3
parentd3f33f3b8ec4646dae3584b648cba142a73d3208 (diff)
downloadpasst-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.c18
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;