]>
Commit | Line | Data |
---|---|---|
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 |
27 | copy_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 | |
38 | The | |
39 | .BR copy_file_range () | |
40 | system call performs an in-kernel copy between two file descriptors | |
ee43ffde | 41 | without the additional cost of transferring data from the kernel to user space |
903b4807 AS |
42 | and then back into the kernel. |
43 | It copies up to | |
44 | .I len | |
45 | bytes of data from file descriptor | |
46 | .I fd_in | |
47 | to file descriptor | |
48 | .IR fd_out , | |
49 | overwriting any data that exists within the requested range of the target file. | |
50 | ||
51 | The following semantics apply for | |
52 | .IR off_in , | |
53 | and similar statements apply to | |
54 | .IR off_out : | |
55 | .IP * 3 | |
56 | If | |
57 | .I off_in | |
58 | is NULL, then bytes are read from | |
59 | .I fd_in | |
ee43ffde | 60 | starting from the file offset, and the file offset is |
903b4807 AS |
61 | adjusted by the number of bytes copied. |
62 | .IP * | |
63 | If | |
64 | .I off_in | |
65 | is not NULL, then | |
66 | .I off_in | |
67 | must point to a buffer that specifies the starting | |
68 | offset where bytes from | |
69 | .I fd_in | |
ee43ffde MK |
70 | will be read. |
71 | The file offset of | |
903b4807 AS |
72 | .I fd_in |
73 | is not changed, but | |
74 | .I off_in | |
75 | is adjusted appropriately. | |
76 | .PP | |
77 | ||
78 | The | |
79 | .I flags | |
ee43ffde MK |
80 | argument is provided to allow for future extensions |
81 | and currently must be to 0. | |
903b4807 AS |
82 | .SH RETURN VALUE |
83 | Upon successful completion, | |
84 | .BR copy_file_range () | |
85 | will return the number of bytes copied between files. | |
86 | This could be less than the length originally requested. | |
87 | ||
88 | On error, | |
89 | .BR copy_file_range () | |
90 | returns \-1 and | |
91 | .I errno | |
92 | is set to indicate the error. | |
93 | .SH ERRORS | |
94 | .TP | |
95 | .B EBADF | |
96 | One or more file descriptors are not valid; or | |
97 | .I fd_in | |
98 | is not open for reading; or | |
99 | .I fd_out | |
100 | is not open for writing; or | |
f0558db8 MK |
101 | the |
102 | .B O_APPEND | |
103 | flag is set for the open file description referred to by | |
104 | .IR fd_out . | |
903b4807 AS |
105 | .TP |
106 | .B EINVAL | |
107 | Requested range extends beyond the end of the source file; or the | |
108 | .I flags | |
109 | argument is not 0. | |
110 | .TP | |
111 | .B EIO | |
ee43ffde | 112 | A low-level I/O error occurred while copying. |
903b4807 AS |
113 | .TP |
114 | .B ENOMEM | |
115 | Out of memory. | |
116 | .TP | |
117 | .B ENOSPC | |
118 | There is not enough space on the target filesystem to complete the copy. | |
119 | .TP | |
120 | .B EXDEV | |
4cfafd79 | 121 | The files referred to by |
903b4807 AS |
122 | .IR file_in " and " file_out |
123 | are not on the same mounted filesystem. | |
124 | .SH VERSIONS | |
125 | The | |
126 | .BR copy_file_range () | |
ee43ffde | 127 | system call first appeared in Linux 4.5. |
903b4807 AS |
128 | .SH CONFORMING TO |
129 | The | |
130 | .BR copy_file_range () | |
131 | system call is a nonstandard Linux extension. | |
132 | .SH NOTES | |
133 | If | |
134 | .I file_in | |
135 | is a sparse file, then | |
136 | .BR copy_file_range () | |
137 | may expand any holes existing in the requested range. | |
138 | Users may benefit from calling | |
139 | .BR copy_file_range () | |
b4fe696c | 140 | in a loop, and using the |
903b4807 | 141 | .BR lseek (2) |
b4fe696c MK |
142 | .BR SEEK_DATA |
143 | and | |
144 | .BR SEEK_HOLE | |
145 | operations to find the locations of data segments. | |
2bea5d44 MK |
146 | |
147 | .BR copy_file_range () | |
148 | gives filesystems an opportunity to implement "copy acceleration" techniques, | |
149 | such as the use of reflinks (i.e., two or more i-nodes that share | |
150 | pointers to the same copy-on-write disk blocks) | |
151 | or 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 |
162 | static loff_t |
163 | copy_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 |
170 | int |
171 | main(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) |