copy_file_range.2: Kernel v5.3 updates

Update with all the missing errors the syscall can return, the
behaviour the syscall should have w.r.t. to copies within single
files, etc.

[Amir] updates for final released version.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
Amir Goldstein 2019-09-26 20:01:19 +03:00 committed by Michael Kerrisk
parent 4985364098
commit 88e75e2c56
1 changed files with 76 additions and 13 deletions

View File

@ -42,9 +42,9 @@ without the additional cost of transferring data from the kernel to user space
and then back into the kernel. and then back into the kernel.
It copies up to It copies up to
.I len .I len
bytes of data from file descriptor bytes of data from the source file descriptor
.I fd_in .I fd_in
to file descriptor to the target file descriptor
.IR fd_out , .IR fd_out ,
overwriting any data that exists within the requested range of the target file. overwriting any data that exists within the requested range of the target file.
.PP .PP
@ -74,6 +74,12 @@ is not changed, but
.I off_in .I off_in
is adjusted appropriately. is adjusted appropriately.
.PP .PP
.I fd_in
and
.I fd_out
can refer to the same file.
If they refer to the same file, then the source and target ranges are not
allowed to overlap.
.PP .PP
The The
.I flags .I flags
@ -84,6 +90,11 @@ Upon successful completion,
.BR copy_file_range () .BR copy_file_range ()
will return the number of bytes copied between files. will return the number of bytes copied between files.
This could be less than the length originally requested. This could be less than the length originally requested.
If the file offset of
.I fd_in
is at or past the end of file, no bytes are copied, and
.BR copy_file_range ()
returns zero.
.PP .PP
On error, On error,
.BR copy_file_range () .BR copy_file_range ()
@ -93,12 +104,16 @@ is set to indicate the error.
.SH ERRORS .SH ERRORS
.TP .TP
.B EBADF .B EBADF
One or more file descriptors are not valid; or One or more file descriptors are not valid.
.TP
.B EBADF
.I fd_in .I fd_in
is not open for reading; or is not open for reading; or
.I fd_out .I fd_out
is not open for writing; or is not open for writing.
the .TP
.B EBADF
The
.B O_APPEND .B O_APPEND
flag is set for the open file description (see flag is set for the open file description (see
.BR open (2)) .BR open (2))
@ -106,24 +121,52 @@ referred to by the file descriptor
.IR fd_out . .IR fd_out .
.TP .TP
.B EFBIG .B EFBIG
An attempt was made to write a file that exceeds the implementation-defined An attempt was made to write at a position past the maximum file offset the
maximum file size or the process's file size limit, kernel supports.
or to write at a position past the maximum allowed offset. .TP
.B EFBIG
An attempt was made to write a range that exceeds the allowed maximum file size.
The maximum file size differs between filesystem implementations and can be
different from the maximum allowed file offset.
.TP
.B EFBIG
An attempt was made to write beyond the process's file size resource limit.
This may also result in the process receiving a
.I SIGXFSZ
signal.
.TP .TP
.B EINVAL .B EINVAL
Requested range extends beyond the end of the source file; or the The
.I flags .I flags
argument is not 0. argument is not 0.
.TP .TP
.B EIO .B EINVAL
A low-level I/O error occurred while copying. .I fd_in
and
.I fd_out
refer to the same file and the source and target ranges overlap.
.TP
.B EINVAL
Either
.I fd_in
or
.I fd_out
is not a regular file.
.TP .TP
.B EISDIR .B EISDIR
Either
.I fd_in .I fd_in
or or
.I fd_out .I fd_out
refers to a directory. refers to a directory.
.TP .TP
.B EOVERFLOW
The requested source or destination range is too large to represent in the
specified data types.
.TP
.B EIO
A low-level I/O error occurred while copying.
.TP
.B ENOMEM .B ENOMEM
Out of memory. Out of memory.
.TP .TP
@ -133,13 +176,33 @@ There is not enough space on the target filesystem to complete the copy.
.B EXDEV .B EXDEV
The files referred to by The files referred to by
.IR file_in " and " file_out .IR file_in " and " file_out
are not on the same mounted filesystem. are not on the same mounted filesystem (pre Linux 5.3).
.TP
.B TXTBSY
Either
.I fd_in
or
.I fd_out
refers to an active swap file.
.TP
.B EPERM
.I fd_out
refers to an immutable file.
.TP
.SH VERSIONS .SH VERSIONS
The The
.BR copy_file_range () .BR copy_file_range ()
system call first appeared in Linux 4.5, but glibc 2.27 provides a user-space system call first appeared in Linux 4.5, but glibc 2.27 provides a user-space
emulation when it is not available. emulation when it is not available.
.\" https://sourceware.org/git/?p=glibc.git;a=commit;f=posix/unistd.h;h=bad7a0c81f501fbbcc79af9eaa4b8254441c4a1f .\" https://sourceware.org/git/?p=glibc.git;a=commit;f=posix/unistd.h;h=bad7a0c81f501fbbcc79af9eaa4b8254441c4a1f
.PP
A major rework of the kernel implementation occurred in 5.3.
Areas of the API that weren't clearly defined were clarified and the API bounds
are much more strictly checked than on earlier kernels.
Applications should target the behaviour and requirements of 5.3 kernels.
.PP
First support for cross-filesystem copies was introduced in Linux 5.3.
Older kernels will return -EXDEV when cross-filesystem copies are attempted.
.SH CONFORMING TO .SH CONFORMING TO
The The
.BR copy_file_range () .BR copy_file_range ()
@ -224,7 +287,7 @@ main(int argc, char **argv)
} }
len \-= ret; len \-= ret;
} while (len > 0); } while (len > 0 && ret > 0);
close(fd_in); close(fd_in);
close(fd_out); close(fd_out);