]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man2/copy_file_range.2
4f42838f25c8f6882177758fc5ed42dfd15cf5bd
[thirdparty/man-pages.git] / man2 / copy_file_range.2
1 .\"This manpage is Copyright (C) 2015 Anna Schumaker <Anna.Schumaker@Netapp.com>
2 .\"
3 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
4 .\"
5 .TH COPY_FILE_RANGE 2 2021-08-27 "Linux" "Linux Programmer's Manual"
6 .SH NAME
7 copy_file_range \- Copy a range of data from one file to another
8 .SH LIBRARY
9 Standard C library
10 .RI ( libc ", " \-lc )
11 .SH SYNOPSIS
12 .nf
13 .B #define _GNU_SOURCE
14 .B #include <unistd.h>
15 .PP
16 .BI "ssize_t copy_file_range(int " fd_in ", off64_t *" off_in ,
17 .BI " int " fd_out ", off64_t *" off_out ,
18 .BI " size_t " len ", unsigned int " flags );
19 .fi
20 .SH DESCRIPTION
21 The
22 .BR copy_file_range ()
23 system call performs an in-kernel copy between two file descriptors
24 without the additional cost of transferring data from the kernel to user space
25 and then back into the kernel.
26 It copies up to
27 .I len
28 bytes of data from the source file descriptor
29 .I fd_in
30 to the target file descriptor
31 .IR fd_out ,
32 overwriting any data that exists within the requested range of the target file.
33 .PP
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
43 starting from the file offset, and the file offset is
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
53 will be read.
54 The file offset of
55 .I fd_in
56 is not changed, but
57 .I off_in
58 is adjusted appropriately.
59 .PP
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.
66 .PP
67 The
68 .I flags
69 argument is provided to allow for future extensions
70 and currently must be set to 0.
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.
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.
81 .PP
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
90 One or more file descriptors are not valid.
91 .TP
92 .B EBADF
93 .I fd_in
94 is not open for reading; or
95 .I fd_out
96 is not open for writing.
97 .TP
98 .B EBADF
99 The
100 .B O_APPEND
101 flag is set for the open file description (see
102 .BR open (2))
103 referred to by the file descriptor
104 .IR fd_out .
105 .TP
106 .B EFBIG
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
118 .B SIGXFSZ
119 signal.
120 .TP
121 .B EINVAL
122 The
123 .I flags
124 argument is not 0.
125 .TP
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.
138 .TP
139 .B EIO
140 A low-level I/O error occurred while copying.
141 .TP
142 .B EISDIR
143 Either
144 .I fd_in
145 or
146 .I fd_out
147 refers to a directory.
148 .TP
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
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.
162 .TP
163 .B ETXTBSY
164 Either
165 .I fd_in
166 or
167 .I fd_out
168 refers to an active swap file.
169 .TP
170 .B EXDEV
171 The files referred to by
172 .IR fd_in " and " fd_out
173 are not on the same mounted filesystem (pre Linux 5.3).
174 .SH VERSIONS
175 The
176 .BR copy_file_range ()
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
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.
188 .SH CONFORMING TO
189 The
190 .BR copy_file_range ()
191 system call is a nonstandard Linux and GNU extension.
192 .SH NOTES
193 If
194 .I fd_in
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 ()
200 in a loop, and using the
201 .BR lseek (2)
202 .BR SEEK_DATA
203 and
204 .BR SEEK_HOLE
205 operations to find the locations of data segments.
206 .PP
207 .BR copy_file_range ()
208 gives filesystems an opportunity to implement "copy acceleration" techniques,
209 such as the use of reflinks (i.e., two or more inodes that share
210 pointers to the same copy-on-write disk blocks)
211 or server-side-copy (in the case of NFS).
212 .SH EXAMPLES
213 .EX
214 #define _GNU_SOURCE
215 #include <fcntl.h>
216 #include <stdio.h>
217 #include <stdlib.h>
218 #include <sys/stat.h>
219 #include <unistd.h>
220
221 int
222 main(int argc, char *argv[])
223 {
224 int fd_in, fd_out;
225 struct stat stat;
226 off64_t len, ret;
227
228 if (argc != 3) {
229 fprintf(stderr, "Usage: %s <source> <destination>\en", argv[0]);
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 }
243
244 len = stat.st_size;
245
246 fd_out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644);
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;
260 } while (len > 0 && ret > 0);
261
262 close(fd_in);
263 close(fd_out);
264 exit(EXIT_SUCCESS);
265 }
266 .EE
267 .SH SEE ALSO
268 .BR lseek (2),
269 .BR sendfile (2),
270 .BR splice (2)