Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

copy_file_range(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)326 / 377 / 285 / 391 (cached kernel tables; hub agrees)
Since (kernel)4.5 (man VERSIONS); cross-filesystem copies and API tightening 5.3
Man pageman2/copy_file_range.2 (local cache, dated 2021-03-22; 5.19 error-semantics rewording from man7.org-current, see notes)
glibc wrapperDeclared in <fcntl.h> with _GNU_SOURCE; copy_file_range@@GLIBC_2.27 (nm -D on glibc 2.41); glibc 2.27 emulates in user space when the kernel lacks the call
Aliases coverednone
Ledger IDSC-copy_file_range

Purpose

copy_file_range() performs an in-kernel copy of up to len bytes from fd_in to fd_out without bouncing the data through user space. Filesystems may accelerate it with reflinks (shared copy-on-write blocks) or server-side copy (NFS). Each offset pointer is optional: when off_in is NULL the copy starts at fd_in’s file offset, which is then advanced; when non-NULL the offset is read from and updated in *off_in while the file offset stays put.

Synopsis

#define _GNU_SOURCE
#include <unistd.h>
ssize_t copy_file_range(int fd_in, off64_t *off_in,
                        int fd_out, off64_t *off_out,
                        size_t len, unsigned int flags);

Arguments and behavior

ArgumentBehavior
fd_in / fd_outRegular files open for reading / writing; O_APPEND on fd_out fails with EBADF. Same file is allowed, but the ranges must not overlap.
off_in / off_outNULL means “use and advance the file offset”; otherwise the caller-owned offset is updated by the number of bytes copied.
lenMaximum bytes to copy; fewer may be transferred.
flagsMust be 0 (EINVAL otherwise); reserved for future extensions.

Return value and errors

Returns the number of bytes copied; 0 means fd_in’s offset was at or past EOF. On error -1 with errno: EBADF, EFBIG (file-size or RLIMIT_FSIZE limits, possibly with SIGXFSZ), EINVAL (flags nonzero, overlapping ranges, non-regular file), EIO, EISDIR, ENOMEM, ENOSPC, EOVERFLOW, EPERM (immutable fd_out), ETXTBSY (active swap file), EXDEV (cross-filesystem before 5.3).

Flags and constants

No flags are defined yet; flags must be 0.

Security and notes

  • The 5.3 rework tightened argument checks; applications should target 5.3 semantics (man VERSIONS).
  • Cross-filesystem copies first worked in 5.3; older kernels return EXDEV. Worklog 1-c records the man-pages 6.19 rewording (man7.org-current): since 5.19 a cross-filesystem attempt is expected to fail with EXDEV or EOPNOTSUPP, and EOPNOTSUPP is the documented error for unsupported device/filename operations.
  • Sparse sources may have holes expanded in the copy; pairing the call in a loop with lseek(2) SEEK_DATA/SEEK_HOLE avoids that.
  • Both descriptors’ dispositions matter: the call can be interrupted, and short copies require looping.

References

  • man2/copy_file_range.2 in the cached man-pages tree (dated 2021-03-22).
  • man-pages 6.19 copy_file_range.2 via man7.org (fetched during task 1-c; source-cache/fetched).
  • Syscalls ledger row SC-copy_file_range; kernel tables in source-cache/kernel.
  • Siblings: sendfile, splice, fallocate.