Skip to content

mv: create cross-device directory entries relative to the destination descriptor - #14971

Open
abendrothj wants to merge 2 commits into
uutils:mainfrom
abendrothj:mv-cross-device-dir-dirfd
Open

abendrothj wants to merge 2 commits into
uutils:mainfrom
abendrothj:mv-cross-device-dir-dirfd

Conversation

@abendrothj

@abendrothj abendrothj commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

When a directory move falls back to copying across filesystems, each destination entry was created by joining a path, and regular files went through fs::copy. A symlink that appeared in the destination while the copy was running was followed, so the content went to wherever it pointed.

The destination directory is now held open and every entry (files, subdirectories, symlinks, FIFOs, hard links) is created relative to it without following symlinks. An entry that appears at a name is unlinked and recreated. Ownership and mode of copied files are set through the open descriptor, dropping setuid/setgid when the chown fails, as the single-file fallback already does. The first commit adds the symlinkat/mkfifoat/linkat helpers to DirFd in uucore.

Closes #14991

Copilot AI balanced review requested due to automatic review settings September 29, 2026 23:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@abendrothj
abendrothj force-pushed the mv-cross-device-dir-dirfd branch from d0cf9fe to f3fc847 Compare September 29, 2026 23:54
Copilot AI balanced review requested due to automatic review settings September 29, 2026 23:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@abendrothj
abendrothj force-pushed the mv-cross-device-dir-dirfd branch from f3fc847 to e3fda2a Compare September 29, 2026 23:55
@codspeed

codspeed Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 27.61%

⚡ 2 improved benchmarks
❌ 1 regressed benchmark
✅ 390 untouched benchmarks
⏩ 54 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Simulation three_39_bit_primes 346.9 ms 1,056.5 ms -67.16%
⚡ Simulation five_38_bit_primes 1.8 s 1.6 s +12.08%
⚡ Simulation thirteen_39_bit_primes 9.4 s 9.1 s +3.05%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing abendrothj:mv-cross-device-dir-dirfd (5e3cb57) with main (cacdd8d)

Open in CodSpeed

Footnotes

  1. 54 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/date/resolution (passes in this run but fails in the 'main' branch)

@abendrothj
abendrothj force-pushed the mv-cross-device-dir-dirfd branch from e3fda2a to 8d392d1 Compare September 30, 2026 02:35
Copilot AI balanced review requested due to automatic review settings September 30, 2026 02:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@abendrothj

Copy link
Copy Markdown
Contributor Author

Opened #14991.

A directory copy needs to create more than files and directories, and each
of those has to land relative to a directory descriptor rather than a
resolved path. `mkfifoat(2)` does not exist everywhere, so the fifo variant
answers Unsupported there and the caller decides; the cfg lists here must
stay in step with the ones in nix.
… descriptor

The cross-device directory fallback built each destination entry by joining
a path, so a symlink dropped into the destination while the copy was running
redirected the file content, and its truncation, anywhere the caller could
write.

Hold the destination directory open and create every entry relative to it.
An entry that appears at a name is unlinked and recreated, which is what GNU
does, rather than being written through. Ownership, permissions and xattrs
then go through the same descriptor, and setuid/setgid are dropped when the
chown did not take, as the single-file fallback already does.

Targets without safe traversal keep the path-based behavior, creating
entries in a way that still refuses to follow a symlink.
Copilot AI balanced review requested due to automatic review settings October 1, 2026 01:14
@abendrothj
abendrothj force-pushed the mv-cross-device-dir-dirfd branch from 8d392d1 to 5e3cb57 Compare October 1, 2026 01:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

This branch has not been deployed

No deployments
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.

mv: cross-device directory move writes through a symlink that appears in the destination

2 participants