}
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. 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.
+ // 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.
//
// As for EINVAL, that is what we see if, for example,
// dst or src refer to a pipe rather than a regular