summaryrefslogtreecommitdiff
path: root/src/internal/poll/copy_file_range_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/poll/copy_file_range_linux.go')
-rw-r--r--src/internal/poll/copy_file_range_linux.go24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/internal/poll/copy_file_range_linux.go b/src/internal/poll/copy_file_range_linux.go
index 66408e4590..ba33f5145d 100644
--- a/src/internal/poll/copy_file_range_linux.go
+++ b/src/internal/poll/copy_file_range_linux.go
@@ -41,18 +41,22 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err
}
n, err := copyFileRange(dst, src, int(max))
switch err {
+ 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. An attempt
- // to do this will result in a EXDEV error.
- //
- // Even though we have checked the kernel version and blocked
- // the attempts to copy_file_range(2) when the kernel version
- // is older than 5.3, but until now the latest kernel (5.19.x)
- // may still return EXDEV error in certain cases.
- //
- // If we see EXDEV, we have not transferred any data,
- // and we can let the caller fall back to generic code.
+ // 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