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