rm: one-file-system#12819
Conversation
Previously --one-file-system was parsed but ignored, so a recursive removal would descend into a mount point and fail with a raw "Device or resource busy" error. Capture the device of the tree root once and, while recursing on Unix, skip any directory whose device differs from it, printing "skipping 'PATH', since it's on a different device" and exiting non-zero.
GNU's --preserve-root=all refuses to recurse across a device boundary, i.e. into a mount point. Accept the optional =all value and, on Unix, skip any directory whose device differs from its parent's — both when named directly on the command line and when reached during recursion — printing the two-line diagnostic and exiting non-zero. This complements --one-file-system, completing GNU-compatible handling of mount points encountered during recursive removal.
|
GNU testsuite comparison: |
Merging this PR will improve performance by 4.11%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | Simulation | rm_single_file |
47.1 ms | 45.2 ms | +4.11% |
Tip
Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.
Comparing DarthStrom:rm-one-file-system (3471175) with main (eee005a)
Footnotes
-
46 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. ↩
|
excellent could you please fix the clippy warnings ? |
clippy's unnecessary_cast fires on `st_dev as u64` on platforms where libc::dev_t is already u64 (Linux), but the cast is required where it is narrower (i32 on macOS). Compute the device once with the same #[allow(clippy::unnecessary_cast)] the rest of the tree uses for st_dev, which also removes the repeated cast at the comparison sites.
|
Sorry about that - apparently my clippy was a bit out-of-date. Hopefully this is an acceptable fix. |
Fixes #7011
Implements two related filesystem-boundary options for
rm, previously parsed but ignored:--one-file-system: while recursing, skip any directory on a different device than the tree root, printingskipping 'PATH', since it's on a different deviceand exiting non-zero (instead of failing with a raw "Device or resource busy").--preserve-root=all: refuse to recurse across a device boundary (into a mount point), checked both for a directory named directly on the command line and for mounts reached during recursion.The device check uses
st_devfromfstatat/lstatand is Unix-only, matching the existing secure-traversal recursion; on other platforms the flags remain no-ops as before.Testing
Added non-regression tests for the single-device case and for rejecting an unknown
--preserve-rootvalue. The authoritative cross-device behavior requires a mount point (root privileges), so it isn't exercised in CI; I verified it manually against the upstream GNU test suite, which now passes.