]>
Commit | Line | Data |
---|---|---|
903b4807 AS |
1 | .\"This manpage is Copyright (C) 2015 Anna Schumaker <Anna.Schumaker@Netapp.com> |
2 | .\" | |
3 | .\" %%%LICENSE_START(VERBATIM) | |
4 | .\" Permission is granted to make and distribute verbatim copies of this | |
5 | .\" manual provided the copyright notice and this permission notice are | |
6 | .\" preserved on all copies. | |
7 | .\" | |
8 | .\" Permission is granted to copy and distribute modified versions of | |
9 | .\" this manual under the conditions for verbatim copying, provided that | |
10 | .\" the entire resulting derived work is distributed under the terms of | |
11 | .\" a permission notice identical to this one. | |
12 | .\" | |
13 | .\" Since the Linux kernel and libraries are constantly changing, this | |
14 | .\" manual page may be incorrect or out-of-date. The author(s) assume | |
15 | .\" no responsibility for errors or omissions, or for damages resulting | |
16 | .\" from the use of the information contained herein. The author(s) may | |
17 | .\" not have taken the same level of care in the production of this | |
18 | .\" manual, which is licensed free of charge, as they might when working | |
19 | .\" professionally. | |
20 | .\" | |
21 | .\" Formatted or processed versions of this manual, if unaccompanied by | |
22 | .\" the source, must acknowledge the copyright and authors of this work. | |
23 | .\" %%%LICENSE_END | |
24 | .\" | |
867c9b34 | 25 | .TH COPY_FILE_RANGE 2 2019-10-10 "Linux" "Linux Programmer's Manual" |
903b4807 AS |
26 | .SH NAME |
27 | copy_file_range \- Copy a range of data from one file to another | |
28 | .SH SYNOPSIS | |
29 | .nf | |
78ab0c7b | 30 | .B #define _GNU_SOURCE |
903b4807 | 31 | .B #include <unistd.h> |
dbfe9c70 | 32 | .PP |
ee43ffde MK |
33 | .BI "ssize_t copy_file_range(int " fd_in ", loff_t *" off_in , |
34 | .BI " int " fd_out ", loff_t *" off_out , | |
35 | .BI " size_t " len ", unsigned int " flags ); | |
903b4807 AS |
36 | .fi |
37 | .SH DESCRIPTION | |
38 | The | |
39 | .BR copy_file_range () | |
40 | system call performs an in-kernel copy between two file descriptors | |
ee43ffde | 41 | without the additional cost of transferring data from the kernel to user space |
903b4807 AS |
42 | and then back into the kernel. |
43 | It copies up to | |
44 | .I len | |
88e75e2c | 45 | bytes of data from the source file descriptor |
903b4807 | 46 | .I fd_in |
88e75e2c | 47 | to the target file descriptor |
903b4807 AS |
48 | .IR fd_out , |
49 | overwriting any data that exists within the requested range of the target file. | |
efeece04 | 50 | .PP |
903b4807 AS |
51 | The following semantics apply for |
52 | .IR off_in , | |
53 | and similar statements apply to | |
54 | .IR off_out : | |
55 | .IP * 3 | |
56 | If | |
57 | .I off_in | |
58 | is NULL, then bytes are read from | |
59 | .I fd_in | |
ee43ffde | 60 | starting from the file offset, and the file offset is |
903b4807 AS |
61 | adjusted by the number of bytes copied. |
62 | .IP * | |
63 | If | |
64 | .I off_in | |
65 | is not NULL, then | |
66 | .I off_in | |
67 | must point to a buffer that specifies the starting | |
68 | offset where bytes from | |
69 | .I fd_in | |
ee43ffde MK |
70 | will be read. |
71 | The file offset of | |
903b4807 AS |
72 | .I fd_in |
73 | is not changed, but | |
74 | .I off_in | |
75 | is adjusted appropriately. | |
76 | .PP | |
88e75e2c AG |
77 | .I fd_in |
78 | and | |
79 | .I fd_out | |
80 | can refer to the same file. | |
81 | If they refer to the same file, then the source and target ranges are not | |
82 | allowed to overlap. | |
efeece04 | 83 | .PP |
903b4807 AS |
84 | The |
85 | .I flags | |
ee43ffde | 86 | argument is provided to allow for future extensions |
b9827733 | 87 | and currently must be set to 0. |
903b4807 AS |
88 | .SH RETURN VALUE |
89 | Upon successful completion, | |
90 | .BR copy_file_range () | |
91 | will return the number of bytes copied between files. | |
92 | This could be less than the length originally requested. | |
88e75e2c AG |
93 | If the file offset of |
94 | .I fd_in | |
95 | is at or past the end of file, no bytes are copied, and | |
96 | .BR copy_file_range () | |
97 | returns zero. | |
efeece04 | 98 | .PP |
903b4807 AS |
99 | On error, |
100 | .BR copy_file_range () | |
101 | returns \-1 and | |
102 | .I errno | |
103 | is set to indicate the error. | |
104 | .SH ERRORS | |
105 | .TP | |
106 | .B EBADF | |
88e75e2c AG |
107 | One or more file descriptors are not valid. |
108 | .TP | |
109 | .B EBADF | |
903b4807 AS |
110 | .I fd_in |
111 | is not open for reading; or | |
112 | .I fd_out | |
88e75e2c AG |
113 | is not open for writing. |
114 | .TP | |
115 | .B EBADF | |
116 | The | |
f0558db8 | 117 | .B O_APPEND |
7f11e32c MK |
118 | flag is set for the open file description (see |
119 | .BR open (2)) | |
120 | referred to by the file descriptor | |
f0558db8 | 121 | .IR fd_out . |
903b4807 | 122 | .TP |
8253adf0 | 123 | .B EFBIG |
88e75e2c AG |
124 | An attempt was made to write at a position past the maximum file offset the |
125 | kernel supports. | |
126 | .TP | |
127 | .B EFBIG | |
128 | An attempt was made to write a range that exceeds the allowed maximum file size. | |
129 | The maximum file size differs between filesystem implementations and can be | |
130 | different from the maximum allowed file offset. | |
131 | .TP | |
132 | .B EFBIG | |
133 | An attempt was made to write beyond the process's file size resource limit. | |
134 | This may also result in the process receiving a | |
135 | .I SIGXFSZ | |
136 | signal. | |
8253adf0 | 137 | .TP |
43d8d5ed | 138 | .B EINVAL |
88e75e2c | 139 | The |
43d8d5ed MK |
140 | .I flags |
141 | argument is not 0. | |
142 | .TP | |
88e75e2c AG |
143 | .B EINVAL |
144 | .I fd_in | |
145 | and | |
146 | .I fd_out | |
147 | refer to the same file and the source and target ranges overlap. | |
148 | .TP | |
149 | .B EINVAL | |
150 | Either | |
151 | .I fd_in | |
152 | or | |
153 | .I fd_out | |
154 | is not a regular file. | |
903b4807 | 155 | .TP |
49a2a105 MK |
156 | .B EIO |
157 | A low-level I/O error occurred while copying. | |
158 | .TP | |
36f69b24 | 159 | .B EISDIR |
88e75e2c | 160 | Either |
36f69b24 MK |
161 | .I fd_in |
162 | or | |
163 | .I fd_out | |
164 | refers to a directory. | |
165 | .TP | |
903b4807 AS |
166 | .B ENOMEM |
167 | Out of memory. | |
168 | .TP | |
169 | .B ENOSPC | |
170 | There is not enough space on the target filesystem to complete the copy. | |
171 | .TP | |
49a2a105 MK |
172 | .B EOVERFLOW |
173 | The requested source or destination range is too large to represent in the | |
174 | specified data types. | |
175 | .TP | |
176 | .B EPERM | |
177 | .I fd_out | |
178 | refers to an immutable file. | |
88e75e2c | 179 | .TP |
13a07cc4 | 180 | .B ETXTBSY |
88e75e2c AG |
181 | Either |
182 | .I fd_in | |
183 | or | |
184 | .I fd_out | |
185 | refers to an active swap file. | |
186 | .TP | |
49a2a105 MK |
187 | .B EXDEV |
188 | The files referred to by | |
3bd3ade0 | 189 | .IR fd_in " and " fd_out |
49a2a105 | 190 | are not on the same mounted filesystem (pre Linux 5.3). |
903b4807 AS |
191 | .SH VERSIONS |
192 | The | |
193 | .BR copy_file_range () | |
78ab0c7b SL |
194 | system call first appeared in Linux 4.5, but glibc 2.27 provides a user-space |
195 | emulation when it is not available. | |
196 | .\" https://sourceware.org/git/?p=glibc.git;a=commit;f=posix/unistd.h;h=bad7a0c81f501fbbcc79af9eaa4b8254441c4a1f | |
88e75e2c AG |
197 | .PP |
198 | A major rework of the kernel implementation occurred in 5.3. | |
199 | Areas of the API that weren't clearly defined were clarified and the API bounds | |
200 | are much more strictly checked than on earlier kernels. | |
201 | Applications should target the behaviour and requirements of 5.3 kernels. | |
202 | .PP | |
203 | First support for cross-filesystem copies was introduced in Linux 5.3. | |
204 | Older kernels will return -EXDEV when cross-filesystem copies are attempted. | |
903b4807 AS |
205 | .SH CONFORMING TO |
206 | The | |
207 | .BR copy_file_range () | |
78ab0c7b | 208 | system call is a nonstandard Linux and GNU extension. |
903b4807 AS |
209 | .SH NOTES |
210 | If | |
3bd3ade0 | 211 | .I fd_in |
903b4807 AS |
212 | is a sparse file, then |
213 | .BR copy_file_range () | |
214 | may expand any holes existing in the requested range. | |
215 | Users may benefit from calling | |
216 | .BR copy_file_range () | |
b4fe696c | 217 | in a loop, and using the |
903b4807 | 218 | .BR lseek (2) |
b4fe696c MK |
219 | .BR SEEK_DATA |
220 | and | |
221 | .BR SEEK_HOLE | |
222 | operations to find the locations of data segments. | |
efeece04 | 223 | .PP |
2bea5d44 MK |
224 | .BR copy_file_range () |
225 | gives filesystems an opportunity to implement "copy acceleration" techniques, | |
fbc8ab9a | 226 | such as the use of reflinks (i.e., two or more inodes that share |
2bea5d44 MK |
227 | pointers to the same copy-on-write disk blocks) |
228 | or server-side-copy (in the case of NFS). | |
903b4807 | 229 | .SH EXAMPLE |
b76974c1 | 230 | .EX |
903b4807 AS |
231 | #define _GNU_SOURCE |
232 | #include <fcntl.h> | |
233 | #include <stdio.h> | |
234 | #include <stdlib.h> | |
235 | #include <sys/stat.h> | |
236 | #include <sys/syscall.h> | |
237 | #include <unistd.h> | |
238 | ||
0e124f35 MK |
239 | /* On versions of glibc before 2.27, we must invoke copy_file_range() |
240 | using syscall(2) */ | |
241 | ||
ee43ffde MK |
242 | static loff_t |
243 | copy_file_range(int fd_in, loff_t *off_in, int fd_out, | |
244 | loff_t *off_out, size_t len, unsigned int flags) | |
903b4807 AS |
245 | { |
246 | return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, | |
247 | off_out, len, flags); | |
248 | } | |
249 | ||
ee43ffde MK |
250 | int |
251 | main(int argc, char **argv) | |
903b4807 AS |
252 | { |
253 | int fd_in, fd_out; | |
254 | struct stat stat; | |
255 | loff_t len, ret; | |
903b4807 AS |
256 | |
257 | if (argc != 3) { | |
d1a71985 | 258 | fprintf(stderr, "Usage: %s <source> <destination>\en", argv[0]); |
903b4807 AS |
259 | exit(EXIT_FAILURE); |
260 | } | |
261 | ||
262 | fd_in = open(argv[1], O_RDONLY); | |
263 | if (fd_in == \-1) { | |
264 | perror("open (argv[1])"); | |
265 | exit(EXIT_FAILURE); | |
266 | } | |
267 | ||
268 | if (fstat(fd_in, &stat) == \-1) { | |
269 | perror("fstat"); | |
270 | exit(EXIT_FAILURE); | |
271 | } | |
ee43ffde | 272 | |
903b4807 AS |
273 | len = stat.st_size; |
274 | ||
ee43ffde | 275 | fd_out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644); |
903b4807 AS |
276 | if (fd_out == \-1) { |
277 | perror("open (argv[2])"); | |
278 | exit(EXIT_FAILURE); | |
279 | } | |
280 | ||
281 | do { | |
282 | ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0); | |
283 | if (ret == \-1) { | |
284 | perror("copy_file_range"); | |
285 | exit(EXIT_FAILURE); | |
286 | } | |
287 | ||
288 | len \-= ret; | |
88e75e2c | 289 | } while (len > 0 && ret > 0); |
903b4807 AS |
290 | |
291 | close(fd_in); | |
292 | close(fd_out); | |
293 | exit(EXIT_SUCCESS); | |
294 | } | |
b76974c1 | 295 | .EE |
903b4807 | 296 | .SH SEE ALSO |
ee43ffde MK |
297 | .BR lseek (2), |
298 | .BR sendfile (2), | |
903b4807 | 299 | .BR splice (2) |