]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man2/copy_file_range.2
All pages: Remove the 5th argument to .TH
[thirdparty/man-pages.git] / man2 / copy_file_range.2
CommitLineData
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
7copy_file_range \- Copy a range of data from one file to another
ab305986
AC
8.SH LIBRARY
9Standard 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
21The
22.BR copy_file_range ()
23system call performs an in-kernel copy between two file descriptors
ee43ffde 24without the additional cost of transferring data from the kernel to user space
903b4807
AS
25and then back into the kernel.
26It copies up to
27.I len
88e75e2c 28bytes of data from the source file descriptor
903b4807 29.I fd_in
88e75e2c 30to the target file descriptor
903b4807
AS
31.IR fd_out ,
32overwriting any data that exists within the requested range of the target file.
efeece04 33.PP
903b4807
AS
34The following semantics apply for
35.IR off_in ,
36and similar statements apply to
37.IR off_out :
38.IP * 3
39If
40.I off_in
41is NULL, then bytes are read from
42.I fd_in
ee43ffde 43starting from the file offset, and the file offset is
903b4807
AS
44adjusted by the number of bytes copied.
45.IP *
46If
47.I off_in
48is not NULL, then
49.I off_in
50must point to a buffer that specifies the starting
51offset where bytes from
52.I fd_in
ee43ffde
MK
53will be read.
54The file offset of
903b4807
AS
55.I fd_in
56is not changed, but
57.I off_in
58is adjusted appropriately.
59.PP
88e75e2c
AG
60.I fd_in
61and
62.I fd_out
63can refer to the same file.
64If they refer to the same file, then the source and target ranges are not
65allowed to overlap.
efeece04 66.PP
903b4807
AS
67The
68.I flags
ee43ffde 69argument is provided to allow for future extensions
b9827733 70and currently must be set to 0.
903b4807
AS
71.SH RETURN VALUE
72Upon successful completion,
73.BR copy_file_range ()
74will return the number of bytes copied between files.
75This could be less than the length originally requested.
88e75e2c
AG
76If the file offset of
77.I fd_in
78is at or past the end of file, no bytes are copied, and
79.BR copy_file_range ()
80returns zero.
efeece04 81.PP
903b4807
AS
82On error,
83.BR copy_file_range ()
84returns \-1 and
85.I errno
86is set to indicate the error.
87.SH ERRORS
88.TP
89.B EBADF
88e75e2c
AG
90One or more file descriptors are not valid.
91.TP
92.B EBADF
903b4807
AS
93.I fd_in
94is not open for reading; or
95.I fd_out
88e75e2c
AG
96is not open for writing.
97.TP
98.B EBADF
99The
f0558db8 100.B O_APPEND
7f11e32c
MK
101flag is set for the open file description (see
102.BR open (2))
103referred to by the file descriptor
f0558db8 104.IR fd_out .
903b4807 105.TP
8253adf0 106.B EFBIG
88e75e2c
AG
107An attempt was made to write at a position past the maximum file offset the
108kernel supports.
109.TP
110.B EFBIG
111An attempt was made to write a range that exceeds the allowed maximum file size.
112The maximum file size differs between filesystem implementations and can be
113different from the maximum allowed file offset.
114.TP
115.B EFBIG
116An attempt was made to write beyond the process's file size resource limit.
117This may also result in the process receiving a
712d2fa5 118.B SIGXFSZ
88e75e2c 119signal.
8253adf0 120.TP
43d8d5ed 121.B EINVAL
88e75e2c 122The
43d8d5ed
MK
123.I flags
124argument is not 0.
125.TP
88e75e2c
AG
126.B EINVAL
127.I fd_in
128and
129.I fd_out
130refer to the same file and the source and target ranges overlap.
131.TP
132.B EINVAL
133Either
134.I fd_in
135or
136.I fd_out
137is not a regular file.
903b4807 138.TP
49a2a105
MK
139.B EIO
140A low-level I/O error occurred while copying.
141.TP
36f69b24 142.B EISDIR
88e75e2c 143Either
36f69b24
MK
144.I fd_in
145or
146.I fd_out
147refers to a directory.
148.TP
903b4807
AS
149.B ENOMEM
150Out of memory.
151.TP
152.B ENOSPC
153There is not enough space on the target filesystem to complete the copy.
154.TP
d7ba612d
AC
155.BR EOPNOTSUPP " (since Linux 5.12)"
156The filesystem does not support this operation.
157.TP
49a2a105
MK
158.B EOVERFLOW
159The requested source or destination range is too large to represent in the
160specified data types.
161.TP
162.B EPERM
163.I fd_out
164refers to an immutable file.
88e75e2c 165.TP
13a07cc4 166.B ETXTBSY
88e75e2c
AG
167Either
168.I fd_in
169or
170.I fd_out
171refers to an active swap file.
172.TP
d7ba612d
AC
173.BR EXDEV " (before Linux 5.3)"
174The files referred to by
175.IR fd_in " and " fd_out
176are not on the same filesystem.
177.TP
178.BR EXDEV " (since Linux 5.12)"
49a2a105 179The files referred to by
3bd3ade0 180.IR fd_in " and " fd_out
d7ba612d
AC
181are not on the same filesystem,
182and the source and target filesystems are not of the same type,
183or do not support cross-filesystem copy.
903b4807
AS
184.SH VERSIONS
185The
186.BR copy_file_range ()
78ab0c7b
SL
187system call first appeared in Linux 4.5, but glibc 2.27 provides a user-space
188emulation 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
191A major rework of the kernel implementation occurred in 5.3.
192Areas of the API that weren't clearly defined were clarified and the API bounds
193are much more strictly checked than on earlier kernels.
194Applications should target the behaviour and requirements of 5.3 kernels.
195.PP
d7ba612d
AC
196Since Linux 5.12,
197cross-filesystem copies can be achieved
198when both filesystems are of the same type,
199and that filesystem implements support for it.
200See BUGS for behavior prior to 5.12.
3113c7f3 201.SH STANDARDS
903b4807
AS
202The
203.BR copy_file_range ()
78ab0c7b 204system call is a nonstandard Linux and GNU extension.
903b4807
AS
205.SH NOTES
206If
3bd3ade0 207.I fd_in
903b4807
AS
208is a sparse file, then
209.BR copy_file_range ()
210may expand any holes existing in the requested range.
211Users may benefit from calling
212.BR copy_file_range ()
b4fe696c 213in a loop, and using the
903b4807 214.BR lseek (2)
1ae6b2c7 215.B SEEK_DATA
b4fe696c 216and
1ae6b2c7 217.B SEEK_HOLE
b4fe696c 218operations to find the locations of data segments.
efeece04 219.PP
2bea5d44
MK
220.BR copy_file_range ()
221gives filesystems an opportunity to implement "copy acceleration" techniques,
fbc8ab9a 222such as the use of reflinks (i.e., two or more inodes that share
2bea5d44
MK
223pointers to the same copy-on-write disk blocks)
224or server-side-copy (in the case of NFS).
d7ba612d
AC
225.SH BUGS
226In Linux kernels 5.3 to 5.11,
227cross-filesystem copies were implemented by the kernel,
228if the operation was not supported by individual filesystems.
229However, on some virtual filesystems,
230the 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 241int
aa1f53cc 242main(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)