From fc8a8673368ffe7c86f9f508132b5410a7c88b36 Mon Sep 17 00:00:00 2001 From: Maximilian Roos Date: Sun, 21 Jun 2026 11:12:46 -0700 Subject: [PATCH] perf(copy): skip redundant chmod after reflink on macOS On macOS/APFS, clonefile() already preserves the source's mode bits, so the post-reflink set_permissions call is redundant; gate it to non-macOS unix. Linux btrfs/XFS still need it because FICLONE clones data extents only and drops the execute bit. Saves one chmod syscall per file for copy-ignored and every other copy.rs caller on macOS. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/copy.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/copy.rs b/src/copy.rs index a96418182..3a5428631 100644 --- a/src/copy.rs +++ b/src/copy.rs @@ -80,15 +80,20 @@ pub fn copy_leaf( } else { match reflink_copy::reflink_or_copy(src, dest) { Ok(_) => { - // Preserve file permissions (especially the execute bit). + // Preserve file permissions (especially the execute bit) — + // needed on Linux, skipped on macOS. // // On btrfs/XFS, reflink (FICLONE ioctl) clones data extents // only — the destination gets umask-based permissions, losing // execute bits. std::fs::copy's fallback preserves permissions // via fchmod, creating an asymmetry in reflink_or_copy. // + // On macOS/APFS, clonefile() already preserves the source's + // mode bits, so this chmod is redundant — skip it to save a + // syscall per file. + // // Refs: ioctl_ficlonerange(2), LWN Articles/331808 - #[cfg(unix)] + #[cfg(all(unix, not(target_os = "macos")))] { fs::set_permissions(dest, src_meta.permissions()) .context("setting destination file permissions")?;