]>
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 | .\" |
6e00b7a8 | 5 | .TH COPY_FILE_RANGE 2 2021-08-27 "Linux" "Linux Programmer's Manual" |
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 | |
49a2a105 MK |
155 | .B EOVERFLOW |
156 | The requested source or destination range is too large to represent in the | |
157 | specified data types. | |
158 | .TP | |
159 | .B EPERM | |
160 | .I fd_out | |
161 | refers to an immutable file. | |
88e75e2c | 162 | .TP |
13a07cc4 | 163 | .B ETXTBSY |
88e75e2c AG |
164 | Either |
165 | .I fd_in | |
166 | or | |
167 | .I fd_out | |
168 | refers to an active swap file. | |
169 | .TP | |
49a2a105 MK |
170 | .B EXDEV |
171 | The files referred to by | |
3bd3ade0 | 172 | .IR fd_in " and " fd_out |
49a2a105 | 173 | are not on the same mounted filesystem (pre Linux 5.3). |
903b4807 AS |
174 | .SH VERSIONS |
175 | The | |
176 | .BR copy_file_range () | |
78ab0c7b SL |
177 | system call first appeared in Linux 4.5, but glibc 2.27 provides a user-space |
178 | emulation when it is not available. | |
179 | .\" https://sourceware.org/git/?p=glibc.git;a=commit;f=posix/unistd.h;h=bad7a0c81f501fbbcc79af9eaa4b8254441c4a1f | |
88e75e2c AG |
180 | .PP |
181 | A major rework of the kernel implementation occurred in 5.3. | |
182 | Areas of the API that weren't clearly defined were clarified and the API bounds | |
183 | are much more strictly checked than on earlier kernels. | |
184 | Applications should target the behaviour and requirements of 5.3 kernels. | |
185 | .PP | |
186 | First support for cross-filesystem copies was introduced in Linux 5.3. | |
187 | Older kernels will return -EXDEV when cross-filesystem copies are attempted. | |
903b4807 AS |
188 | .SH CONFORMING TO |
189 | The | |
190 | .BR copy_file_range () | |
78ab0c7b | 191 | system call is a nonstandard Linux and GNU extension. |
903b4807 AS |
192 | .SH NOTES |
193 | If | |
3bd3ade0 | 194 | .I fd_in |
903b4807 AS |
195 | is a sparse file, then |
196 | .BR copy_file_range () | |
197 | may expand any holes existing in the requested range. | |
198 | Users may benefit from calling | |
199 | .BR copy_file_range () | |
b4fe696c | 200 | in a loop, and using the |
903b4807 | 201 | .BR lseek (2) |
1ae6b2c7 | 202 | .B SEEK_DATA |
b4fe696c | 203 | and |
1ae6b2c7 | 204 | .B SEEK_HOLE |
b4fe696c | 205 | operations to find the locations of data segments. |
efeece04 | 206 | .PP |
2bea5d44 MK |
207 | .BR copy_file_range () |
208 | gives filesystems an opportunity to implement "copy acceleration" techniques, | |
fbc8ab9a | 209 | such as the use of reflinks (i.e., two or more inodes that share |
2bea5d44 MK |
210 | pointers to the same copy-on-write disk blocks) |
211 | or server-side-copy (in the case of NFS). | |
a14af333 | 212 | .SH EXAMPLES |
b76974c1 | 213 | .EX |
903b4807 AS |
214 | #define _GNU_SOURCE |
215 | #include <fcntl.h> | |
216 | #include <stdio.h> | |
217 | #include <stdlib.h> | |
218 | #include <sys/stat.h> | |
903b4807 AS |
219 | #include <unistd.h> |
220 | ||
ee43ffde | 221 | int |
aa1f53cc | 222 | main(int argc, char *argv[]) |
903b4807 AS |
223 | { |
224 | int fd_in, fd_out; | |
225 | struct stat stat; | |
76c5631f | 226 | off64_t len, ret; |
903b4807 AS |
227 | |
228 | if (argc != 3) { | |
d1a71985 | 229 | fprintf(stderr, "Usage: %s <source> <destination>\en", argv[0]); |
903b4807 AS |
230 | exit(EXIT_FAILURE); |
231 | } | |
232 | ||
233 | fd_in = open(argv[1], O_RDONLY); | |
234 | if (fd_in == \-1) { | |
235 | perror("open (argv[1])"); | |
236 | exit(EXIT_FAILURE); | |
237 | } | |
238 | ||
239 | if (fstat(fd_in, &stat) == \-1) { | |
240 | perror("fstat"); | |
241 | exit(EXIT_FAILURE); | |
242 | } | |
ee43ffde | 243 | |
903b4807 AS |
244 | len = stat.st_size; |
245 | ||
ee43ffde | 246 | fd_out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644); |
903b4807 AS |
247 | if (fd_out == \-1) { |
248 | perror("open (argv[2])"); | |
249 | exit(EXIT_FAILURE); | |
250 | } | |
251 | ||
252 | do { | |
253 | ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0); | |
254 | if (ret == \-1) { | |
255 | perror("copy_file_range"); | |
256 | exit(EXIT_FAILURE); | |
257 | } | |
258 | ||
259 | len \-= ret; | |
88e75e2c | 260 | } while (len > 0 && ret > 0); |
903b4807 AS |
261 | |
262 | close(fd_in); | |
263 | close(fd_out); | |
264 | exit(EXIT_SUCCESS); | |
265 | } | |
b76974c1 | 266 | .EE |
903b4807 | 267 | .SH SEE ALSO |
ee43ffde MK |
268 | .BR lseek (2), |
269 | .BR sendfile (2), | |
903b4807 | 270 | .BR splice (2) |