Source file src/internal/poll/copy_file_range_freebsd.go
1 // Copyright 2024 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package poll 6 7 import ( 8 "internal/syscall/unix" 9 "syscall" 10 ) 11 12 func supportCopyFileRange() bool { 13 return unix.SupportCopyFileRange() 14 } 15 16 // For best performance, call copy_file_range() with the largest len value 17 // possible. It is interruptible on most file systems, so there is no penalty 18 // for using very large len values, even SSIZE_MAX. 19 const maxCopyFileRangeRound = 1<<31 - 1 20 21 func handleCopyFileRangeErr(err error, copied, written int64) (bool, error) { 22 switch err { 23 case syscall.ENOSYS: 24 // The copy_file_range(2) function first appeared in FreeBSD 13.0. 25 // Go supports FreeBSD >= 12, so the system call 26 // may not be present. We've detected the FreeBSD version with 27 // unix.SupportCopyFileRange() at the beginning of this function, 28 // but we still want to check for ENOSYS here to prevent some rare 29 // case like https://go.dev/issue/58592 30 // 31 // If we see ENOSYS, we have certainly not transferred 32 // any data, so we can tell the caller that we 33 // couldn't handle the transfer and let them fall 34 // back to more generic code. 35 return false, nil 36 case syscall.EFBIG, syscall.EINVAL, syscall.EIO: 37 // For EFBIG, the copy has exceeds the process's file size limit 38 // or the maximum file size for the filesystem dst resides on, in 39 // this case, we leave it to generic copy. 40 // 41 // For EINVAL, there could be a few reasons: 42 // 1. Either dst or src refers to a file object that 43 // is not a regular file, for instance, a pipe. 44 // 2. src and dst refer to the same file and byte ranges 45 // overlap. 46 // 3. The flags argument is not 0. 47 // Neither of these cases should be considered handled by 48 // copy_file_range(2) because there is no data transfer, so 49 // just fall back to generic copy. 50 return false, nil 51 } 52 return true, err 53 } 54