From 1bf5796cae9e8f7b55402f199a1eec82a092abb7 Mon Sep 17 00:00:00 2001 From: Ben Burkert Date: Wed, 5 Sep 2018 10:20:26 -0700 Subject: [PATCH] internal/poll: fall back on unsupported splice from unix socket Gracefully fallback to a userspace copy when the kernel does not support splice(2) on a unix domain socket. EINVAL is returned by the splice syscall if it does not support unix domain sockets. Keeping the handled return value as false when the first splice call fails with EINVAL will cause the caller to fall back to a userspace copy. Fixes #27513 Change-Id: I4b10c1900ba3c096cb32edb7c8a6044f468efb52 Reviewed-on: https://go-review.googlesource.com/133575 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Tobias Klauser --- src/internal/poll/splice_linux.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/internal/poll/splice_linux.go b/src/internal/poll/splice_linux.go index aa237e587a..9ba94d648b 100644 --- a/src/internal/poll/splice_linux.go +++ b/src/internal/poll/splice_linux.go @@ -32,8 +32,6 @@ func Splice(dst, src *FD, remain int64) (written int64, handled bool, sc string, return 0, false, sc, err } defer destroyTempPipe(prfd, pwfd) - // From here on, the operation should be considered handled, - // even if Splice doesn't transfer any data. var inPipe, n int for err == nil && remain > 0 { max := maxSpliceSize @@ -41,6 +39,12 @@ func Splice(dst, src *FD, remain int64) (written int64, handled bool, sc string, max = int(remain) } inPipe, err = spliceDrain(pwfd, src, max) + // the operation is considered handled if splice returns no error, or + // an error other than EINVAL. An EINVAL means the kernel does not + // support splice for the socket type of dst and/or src. The failed + // syscall does not consume any data so it is safe to fall back to a + // generic copy. + handled = handled || (err != syscall.EINVAL) // spliceDrain should never return EAGAIN, so if err != nil, // Splice cannot continue. If inPipe == 0 && err == nil, // src is at EOF, and the transfer is complete. @@ -54,7 +58,7 @@ func Splice(dst, src *FD, remain int64) (written int64, handled bool, sc string, } } if err != nil { - return written, true, "splice", err + return written, handled, "splice", err } return written, true, "", nil } -- 2.50.0