From 1c50484335ff8c752f872cf730f262b66280b5be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Mon, 5 Sep 2022 08:37:48 +0000 Subject: [PATCH] Revert "internal/poll: drop redundant ENOSYS and EXDEV error checks in CopyFileRange()" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts https://go.dev/cl/425881. Reason for revert: broke make.bash on linux/amd64 with Linux 5.19.6. [...] Building Go toolchain2 using go_bootstrap and Go toolchain1. go install internal/unsafeheader: copying /tmp/go-build4206185186/b007/_pkg_.a to /home/mvdan/tip/pkg/linux_amd64/internal/unsafeheader.a: write /home/mvdan/tip/pkg/linux_amd64/internal/unsafeheader.a: copy_file_range: invalid cross-device link go install internal/goarch: copying /tmp/go-build4206185186/b006/_pkg_.a to /home/mvdan/tip/pkg/linux_amd64/internal/goarch.a: write /home/mvdan/tip/pkg/linux_amd64/internal/goarch.a: copy_file_range: invalid cross-device link [...] Change-Id: I793856935d4315a870c2d31da46be00cc342b5f8 Reviewed-on: https://go-review.googlesource.com/c/go/+/428396 Reviewed-by: Wayne Zuo Reviewed-by: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Run-TryBot: Daniel Martí Reviewed-by: hopehook Reviewed-by: Andy Pan TryBot-Result: Gopher Robot Reviewed-by: Tobias Klauser Run-TryBot: Ian Lance Taylor Reviewed-by: Michael Pratt --- src/internal/poll/copy_file_range_linux.go | 31 ++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/internal/poll/copy_file_range_linux.go b/src/internal/poll/copy_file_range_linux.go index 4ac17d6a05..ba33f5145d 100644 --- a/src/internal/poll/copy_file_range_linux.go +++ b/src/internal/poll/copy_file_range_linux.go @@ -41,9 +41,25 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err } n, err := copyFileRange(dst, src, int(max)) switch err { - case syscall.EINVAL, syscall.EIO, syscall.EOPNOTSUPP, syscall.EPERM: - // EINVAL is what we see if, for example, - // dst or src refers to a pipe rather than a regular + case syscall.ENOSYS: + // copy_file_range(2) was introduced in Linux 4.5. + // Go supports Linux >= 2.6.33, so the system call + // may not be present. + // + // If we see ENOSYS, we have certainly not transferred + // any data, so we can tell the caller that we + // couldn't handle the transfer and let them fall + // back to more generic code. + return 0, false, nil + case syscall.EXDEV, syscall.EINVAL, syscall.EIO, syscall.EOPNOTSUPP, syscall.EPERM: + // Prior to Linux 5.3, it was not possible to + // copy_file_range across file systems. Similarly to + // the ENOSYS case above, if we see EXDEV, we have + // not transferred any data, and we can let the caller + // fall back to generic code. + // + // As for EINVAL, that is what we see if, for example, + // dst or src refer to a pipe rather than a regular // file. This is another case where no data has been // transferred, so we consider it unhandled. // @@ -54,10 +70,9 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err // See issue #40731. // // If the process is running inside a Docker container, - // we might see EPERM instead of ENOSYS. See issue #40893. - // Since EPERM might also be a legitimate error: operation not permitted, - // we should still keep this error even if we have the previous kernel version 5.3 check - // and don't mark copy_file_range(2) as unsupported. + // we might see EPERM instead of ENOSYS. See issue + // #40893. Since EPERM might also be a legitimate error, + // don't mark copy_file_range(2) as unsupported. return 0, false, nil case nil: if n == 0 { @@ -68,7 +83,7 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err if written == 0 { return 0, false, nil } - // Otherwise, src is at EOF, which means + // Otherwise src is at EOF, which means // we are done. return written, true, nil }