1copy_file_range(2) System Calls Manual copy_file_range(2)
2
3
4
6 copy_file_range - Copy a range of data from one file to another
7
9 Standard C library (libc, -lc)
10
12 #define _GNU_SOURCE
13 #define _FILE_OFFSET_BITS 64
14 #include <unistd.h>
15
16 ssize_t copy_file_range(int fd_in, off_t *_Nullable off_in,
17 int fd_out, off_t *_Nullable off_out,
18 size_t len, unsigned int flags);
19
21 The copy_file_range() system call performs an in-kernel copy between
22 two file descriptors without the additional cost of transferring data
23 from the kernel to user space and then back into the kernel. It copies
24 up to len bytes of data from the source file descriptor fd_in to the
25 target file descriptor fd_out, overwriting any data that exists within
26 the requested range of the target file.
27
28 The following semantics apply for off_in, and similar statements apply
29 to off_out:
30
31 • If off_in is NULL, then bytes are read from fd_in starting from the
32 file offset, and the file offset is adjusted by the number of bytes
33 copied.
34
35 • If off_in is not NULL, then off_in must point to a buffer that spec‐
36 ifies the starting offset where bytes from fd_in will be read. The
37 file offset of fd_in is not changed, but off_in is adjusted appro‐
38 priately.
39
40 fd_in and fd_out can refer to the same file. If they refer to the same
41 file, then the source and target ranges are not allowed to overlap.
42
43 The flags argument is provided to allow for future extensions and cur‐
44 rently must be set to 0.
45
47 Upon successful completion, copy_file_range() will return the number of
48 bytes copied between files. This could be less than the length origi‐
49 nally requested. If the file offset of fd_in is at or past the end of
50 file, no bytes are copied, and copy_file_range() returns zero.
51
52 On error, copy_file_range() returns -1 and errno is set to indicate the
53 error.
54
56 EBADF One or more file descriptors are not valid.
57
58 EBADF fd_in is not open for reading; or fd_out is not open for writ‐
59 ing.
60
61 EBADF The O_APPEND flag is set for the open file description (see
62 open(2)) referred to by the file descriptor fd_out.
63
64 EFBIG An attempt was made to write at a position past the maximum file
65 offset the kernel supports.
66
67 EFBIG An attempt was made to write a range that exceeds the allowed
68 maximum file size. The maximum file size differs between
69 filesystem implementations and can be different from the maximum
70 allowed file offset.
71
72 EFBIG An attempt was made to write beyond the process's file size re‐
73 source limit. This may also result in the process receiving a
74 SIGXFSZ signal.
75
76 EINVAL The flags argument is not 0.
77
78 EINVAL fd_in and fd_out refer to the same file and the source and tar‐
79 get ranges overlap.
80
81 EINVAL Either fd_in or fd_out is not a regular file.
82
83 EIO A low-level I/O error occurred while copying.
84
85 EISDIR Either fd_in or fd_out refers to a directory.
86
87 ENOMEM Out of memory.
88
89 ENOSPC There is not enough space on the target filesystem to complete
90 the copy.
91
92 EOPNOTSUPP (since Linux 5.19)
93 The filesystem does not support this operation.
94
95 EOVERFLOW
96 The requested source or destination range is too large to repre‐
97 sent in the specified data types.
98
99 EPERM fd_out refers to an immutable file.
100
101 ETXTBSY
102 Either fd_in or fd_out refers to an active swap file.
103
104 EXDEV (before Linux 5.3)
105 The files referred to by fd_in and fd_out are not on the same
106 filesystem.
107
108 EXDEV (since Linux 5.19)
109 The files referred to by fd_in and fd_out are not on the same
110 filesystem, and the source and target filesystems are not of the
111 same type, or do not support cross-filesystem copy.
112
114 A major rework of the kernel implementation occurred in Linux 5.3. Ar‐
115 eas of the API that weren't clearly defined were clarified and the API
116 bounds are much more strictly checked than on earlier kernels.
117
118 Since Linux 5.19, cross-filesystem copies can be achieved when both
119 filesystems are of the same type, and that filesystem implements sup‐
120 port for it. See BUGS for behavior prior to Linux 5.19.
121
122 Applications should target the behaviour and requirements of Linux
123 5.19, that was also backported to earlier stable kernels.
124
126 Linux, GNU.
127
129 Linux 4.5, but glibc 2.27 provides a user-space emulation when it is
130 not available.
131
133 If fd_in is a sparse file, then copy_file_range() may expand any holes
134 existing in the requested range. Users may benefit from calling
135 copy_file_range() in a loop, and using the lseek(2) SEEK_DATA and
136 SEEK_HOLE operations to find the locations of data segments.
137
138 copy_file_range() gives filesystems an opportunity to implement "copy
139 acceleration" techniques, such as the use of reflinks (i.e., two or
140 more inodes that share pointers to the same copy-on-write disk blocks)
141 or server-side-copy (in the case of NFS).
142
143 _FILE_OFFSET_BITS should be defined to be 64 in code that uses non-null
144 off_in or off_out or that takes the address of copy_file_range, if the
145 code is intended to be portable to traditional 32-bit x86 and ARM plat‐
146 forms where off_t's width defaults to 32 bits.
147
149 In Linux 5.3 to Linux 5.18, cross-filesystem copies were implemented by
150 the kernel, if the operation was not supported by individual filesys‐
151 tems. However, on some virtual filesystems, the call failed to copy,
152 while still reporting success.
153
155 #define _GNU_SOURCE
156 #define _FILE_OFFSET_BITS 64
157 #include <fcntl.h>
158 #include <stdio.h>
159 #include <stdlib.h>
160 #include <sys/stat.h>
161 #include <unistd.h>
162
163 int
164 main(int argc, char *argv[])
165 {
166 int fd_in, fd_out;
167 off_t len, ret;
168 struct stat stat;
169
170 if (argc != 3) {
171 fprintf(stderr, "Usage: %s <source> <destination>\n", argv[0]);
172 exit(EXIT_FAILURE);
173 }
174
175 fd_in = open(argv[1], O_RDONLY);
176 if (fd_in == -1) {
177 perror("open (argv[1])");
178 exit(EXIT_FAILURE);
179 }
180
181 if (fstat(fd_in, &stat) == -1) {
182 perror("fstat");
183 exit(EXIT_FAILURE);
184 }
185
186 len = stat.st_size;
187
188 fd_out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644);
189 if (fd_out == -1) {
190 perror("open (argv[2])");
191 exit(EXIT_FAILURE);
192 }
193
194 do {
195 ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0);
196 if (ret == -1) {
197 perror("copy_file_range");
198 exit(EXIT_FAILURE);
199 }
200
201 len -= ret;
202 } while (len > 0 && ret > 0);
203
204 close(fd_in);
205 close(fd_out);
206 exit(EXIT_SUCCESS);
207 }
208
210 lseek(2), sendfile(2), splice(2)
211
212
213
214Linux man-pages 6.05 2023-07-15 copy_file_range(2)