Skip to content

cp: honor --reflink=never on macOS - #14076

Open
nagendramohan wants to merge 1 commit into
uutils:mainfrom
nagendramohan:cp-macos-reflink-never-14052
Open

cp: honor --reflink=never on macOS#14076
nagendramohan wants to merge 1 commit into
uutils:mainfrom
nagendramohan:cp-macos-reflink-never-14052

Conversation

@nagendramohan

Copy link
Copy Markdown

On macOS, copy_on_write() called clonefile(2) unconditionally and never consulted
reflink_mode, so --reflink=never still cloned. Because clonefile(2) COW-shares the
source's blocks and copies its metadata (including mtime), a plain cp on APFS gave the
destination the source's mtime, where GNU and BSD cp stamp the copy's own time.

This is the same class as #13064; the fix in #13065 only touched platform/linux.rs, leaving
the macOS path uncovered.

Fix: skip the clonefile(2) attempt when reflink_mode is Never and fall through to the
existing byte-copy path, mirroring the Linux ReflinkMode::Never handling.

Verified on APFS: with --reflink=never, a 40 MB copy now consumes ~40 MB and the destination
gets its own mtime; default cp still clones (no regression to the fast path). Added a macOS
regression test asserting --reflink=never does not leave the destination with the source's mtime.

Fixes #14052

On macOS, copy_on_write() called clonefile(2) unconditionally and never
consulted reflink_mode, so `--reflink=never` still cloned. Because
clonefile(2) COW-shares the source's blocks and copies its metadata
(including mtime), a plain `cp` on APFS gave the destination the
source's mtime, where GNU and BSD cp stamp the copy's own time.

Skip the clonefile attempt when reflink_mode is Never and fall through
to the existing byte-copy path, mirroring the Linux ReflinkMode::Never
handling (the fix in uutils#13065 only covered platform/linux.rs).

Add a macOS regression test: --reflink=never must not leave the
destination with the source's (old) mtime.

Fixes uutils#14052
@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/tail/tail-n0f (fails in this run but passes in the 'main' branch)
Note: The gnu test tests/env/env-signal-handler was skipped on 'main' but is now failing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cp: --reflink=never is ignored on macOS, and clonefile(2) silently preserves timestamps

1 participant