...
Source file
src/internal/poll/copy_file_range_unix.go
1
2
3
4
5
6
7 package poll
8
9 import "internal/syscall/unix"
10
11
12
13 func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err error) {
14 if !supportCopyFileRange() {
15 return 0, false, nil
16 }
17
18 for remain > 0 {
19 max := min(remain, maxCopyFileRangeRound)
20 n, e := copyFileRange(dst, src, int(max))
21 if n > 0 {
22 remain -= n
23 written += n
24 }
25 handled, err = handleCopyFileRangeErr(e, n, written)
26 if n == 0 || !handled || err != nil {
27 return
28 }
29 }
30
31 return written, true, nil
32 }
33
34
35 func copyFileRange(dst, src *FD, max int) (written int64, err error) {
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 if err := dst.writeLock(); err != nil {
56 return 0, err
57 }
58 defer dst.writeUnlock()
59 if err := src.readLock(); err != nil {
60 return 0, err
61 }
62 defer src.readUnlock()
63 return ignoringEINTR2(func() (int64, error) {
64 n, err := unix.CopyFileRange(src.Sysfd, nil, dst.Sysfd, nil, max, 0)
65 return int64(n), err
66 })
67 }
68
View as plain text