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