Expand description
Low-level data-copy primitive used by the copy path.
This replaces std::fs::copy so the copy path can keep the destination fd
open across the data copy and the subsequent metadata operations (closing
the TOCTOU window between writing bytes and setting times/owner/mode).
The copy uses a three-tier fallback chain, fastest first:
- the in-kernel
copy_file_rangesyscall, which is reflink- and server-side-copy capable (e.g. on Btrfs/XFS/NFSv4.2); - when the kernel or filesystem cannot satisfy that, a sparse-aware
userspace copy that walks the source with
SEEK_DATA/SEEK_HOLEand preserves holes; - when the filesystem does not even support
SEEK_DATA/SEEK_HOLE(some FUSE/older/unusual filesystems returnEINVAL/ENOTSUPfor thoselseekwhences), a plain dense read/write copy loop, which always works on any regular file (this mirrors whatstd::fs::copywould have done and exists purely for robustness — it does not preserve holes).
§Snapshot-size semantics
Callers pass len, the size captured when the source was classified. Both
the primary and fallback paths copy up to len and agree on the result:
- a source that grew after classification is intentionally not
over-copied — we copy at most
lenbytes anddstends atlen; - a source that shrank below
len(e.g. a concurrent truncate — holding the fd does not prevent it) copies and returns only what the source provides and sizesdstto that actual end, not tolen(no spurious trailing padding); - a legitimate sparse trailing hole (the source’s logical size still
equals
len) keepsdstsized tolen. Whether the trailing region is left unallocated depends on the path: the sparse-aware fallback (tier 2) preserves the hole, and the primarycopy_file_range(tier 1) does so only on reflink/sparse-capable filesystems (e.g. Btrfs/XFS) — on others (e.g. ext4) the size is stilllenbut the region may be fully allocated.
§Durability
These are synchronous syscalls, so once they return the writes are in the
kernel. This function deliberately does not fsync/flush — durability
is out of scope here. mtime correctness is the caller’s responsibility (it
sets times after this returns).
Functions§
- copy_
file_ range_ all - Copy up to
lenbytes fromsrctodstusing the in-kernelcopy_file_range(reflink/server-side capable), falling back to a sparse-aware userspace copy when the kernel/filesystem can’t. Both files are already open; offsets start at0. Returns the number of bytes copied.