]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man2/copy_file_range.2
mdoc.7: wfix
[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.\"
97986708 25.TH COPY 2 2016-03-15 "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
30.B #include <sys/syscall.h>
31.B #include <unistd.h>
32
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
45bytes of data from file descriptor
46.I fd_in
47to file descriptor
48.IR fd_out ,
49overwriting any data that exists within the requested range of the target file.
50
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
77
78The
79.I flags
ee43ffde
MK
80argument is provided to allow for future extensions
81and currently must be to 0.
903b4807
AS
82.SH RETURN VALUE
83Upon successful completion,
84.BR copy_file_range ()
85will return the number of bytes copied between files.
86This could be less than the length originally requested.
87
88On error,
89.BR copy_file_range ()
90returns \-1 and
91.I errno
92is set to indicate the error.
93.SH ERRORS
94.TP
95.B EBADF
96One or more file descriptors are not valid; or
97.I fd_in
98is not open for reading; or
99.I fd_out
100is not open for writing; or
f0558db8
MK
101the
102.B O_APPEND
103flag is set for the open file description referred to by
104.IR fd_out .
903b4807
AS
105.TP
106.B EINVAL
107Requested range extends beyond the end of the source file; or the
108.I flags
109argument is not 0.
110.TP
111.B EIO
ee43ffde 112A low-level I/O error occurred while copying.
903b4807
AS
113.TP
114.B ENOMEM
115Out of memory.
116.TP
117.B ENOSPC
118There is not enough space on the target filesystem to complete the copy.
119.TP
120.B EXDEV
4cfafd79 121The files referred to by
903b4807
AS
122.IR file_in " and " file_out
123are not on the same mounted filesystem.
124.SH VERSIONS
125The
126.BR copy_file_range ()
ee43ffde 127system call first appeared in Linux 4.5.
903b4807
AS
128.SH CONFORMING TO
129The
130.BR copy_file_range ()
131system call is a nonstandard Linux extension.
132.SH NOTES
133If
134.I file_in
135is a sparse file, then
136.BR copy_file_range ()
137may expand any holes existing in the requested range.
138Users may benefit from calling
139.BR copy_file_range ()
b4fe696c 140in a loop, and using the
903b4807 141.BR lseek (2)
b4fe696c
MK
142.BR SEEK_DATA
143and
144.BR SEEK_HOLE
145operations to find the locations of data segments.
2bea5d44
MK
146
147.BR copy_file_range ()
148gives filesystems an opportunity to implement "copy acceleration" techniques,
149such as the use of reflinks (i.e., two or more i-nodes that share
150pointers to the same copy-on-write disk blocks)
151or server-side-copy (in the case of NFS).
903b4807
AS
152.SH EXAMPLE
153.nf
154#define _GNU_SOURCE
155#include <fcntl.h>
156#include <stdio.h>
157#include <stdlib.h>
158#include <sys/stat.h>
159#include <sys/syscall.h>
160#include <unistd.h>
161
ee43ffde
MK
162static loff_t
163copy_file_range(int fd_in, loff_t *off_in, int fd_out,
164 loff_t *off_out, size_t len, unsigned int flags)
903b4807
AS
165{
166 return syscall(__NR_copy_file_range, fd_in, off_in, fd_out,
167 off_out, len, flags);
168}
169
ee43ffde
MK
170int
171main(int argc, char **argv)
903b4807
AS
172{
173 int fd_in, fd_out;
174 struct stat stat;
175 loff_t len, ret;
903b4807
AS
176
177 if (argc != 3) {
178 fprintf(stderr, "Usage: %s <source> <destination>\\n", argv[0]);
179 exit(EXIT_FAILURE);
180 }
181
182 fd_in = open(argv[1], O_RDONLY);
183 if (fd_in == \-1) {
184 perror("open (argv[1])");
185 exit(EXIT_FAILURE);
186 }
187
188 if (fstat(fd_in, &stat) == \-1) {
189 perror("fstat");
190 exit(EXIT_FAILURE);
191 }
ee43ffde 192
903b4807
AS
193 len = stat.st_size;
194
ee43ffde 195 fd_out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644);
903b4807
AS
196 if (fd_out == \-1) {
197 perror("open (argv[2])");
198 exit(EXIT_FAILURE);
199 }
200
201 do {
202 ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0);
203 if (ret == \-1) {
204 perror("copy_file_range");
205 exit(EXIT_FAILURE);
206 }
207
208 len \-= ret;
209 } while (len > 0);
210
211 close(fd_in);
212 close(fd_out);
213 exit(EXIT_SUCCESS);
214}
215.fi
216.SH SEE ALSO
ee43ffde
MK
217.BR lseek (2),
218.BR sendfile (2),
903b4807 219.BR splice (2)