Attempt to use reflinks by default on Linux#18117
Merged
Conversation
On Linux, default to `LinkMode::Clone` (reflink) instead of `LinkMode::Hardlink`. The clone fallback chain is now: Clone -> Hardlink -> Copy, so on filesystems that don't support reflinks (e.g., ext4), we try one reflink, fail, then fall back to hardlinks — which is what we were doing before. The overhead of the single failed FICLONE ioctl is negligible (~80ms in benchmarks). On filesystems that support reflinks (btrfs, XFS, bcachefs), users get copy-on-write benefits automatically without needing to opt in. https://claude.ai/code/session_015S1a39fWo8vqMHhjUe8uoG
Replace UV_INTERNAL__TEST_EXPECT_REFLINK and UV_INTERNAL__TEST_DIR usage in link tests with two new env vars: - UV_INTERNAL__TEST_REFLINK_FS: path on a reflink-capable filesystem - UV_INTERNAL__TEST_TMP_FS: path on a non-reflink filesystem This enables comprehensive test coverage: - Same-device reflink (both dirs on reflink fs) - Same-device fallback (both dirs on non-reflink fs) - Cross-device clone fallback (reflink fs -> tmpfs and vice versa) - Cross-device hardlink fallback (must fall back to copy) - Cross-device symlink (should work across devices) - Cross-device copy (sanity check) The Linux CI job now creates both a btrfs loopback and a tmpfs mount. The macOS CI job sets TEST_REFLINK_FS to the runner temp (APFS).
1c3d5fa to
6038865
Compare
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
6038865 to
529ce94
Compare
- Remove redundant test_reflink_fails_on_tmp_fs (assertion belongs in tests using nocow fs) - Rename test_clone_fallback_on_tmp_fs -> test_clone_fallback_on_nocow_fs - Simplify cross-device tests: use alt_tempdir + test_tempdir instead of cow+alt pairs - Merge bidirectional cross-device test pairs into single tests - All cross-device assertions now expect exactly Copy (not Hardlink || Copy) - Symlink cross-device asserts exactly Symlink - Remove 'sanity check' from doc comment - Restructure pip_install tests: install_cross_device, install_copy_on_write_fs, install_no_copy_on_write_fs - Tests use default link mode instead of explicit --link-mode - Show fallback warning in cross-device test instead of filtering it - Add with_cache_on_nocow_fs and with_working_dir_on_nocow_fs test helpers - Update all documentation to reflect clone default on macOS and Linux - Fix prettier formatting in docker.md
zanieb
commented
Feb 20, 2026
zanieb
commented
Feb 20, 2026
…able - with_cache_on_fs/with_working_dir_on_fs now accept a name parameter - Filters now produce [ALT_FS]/[CACHE_DIR]/, [COW_FS]/[TEMP_DIR]/, etc. - Inline the canonical variable in with_working_dir_on_fs
- install_cross_device_explicit_copy: --link-mode copy suppresses the warning - install_cross_device_symlink: symlinks work across devices without warning
EliteTK
approved these changes
Feb 23, 2026
Contributor
EliteTK
left a comment
There was a problem hiding this comment.
Seams neat, I assume I am understanding it correctly that if I'm on Linux on ext4, this won't start complaining about the inability to reflink when a hardlink succeeds instead right?
.github/workflows/test.yml
Outdated
|
|
||
| - name: "Create HFS+ RAM disk (no reflink support)" | ||
| run: | | ||
| RAMDISK=$(hdiutil attach -nomount ram://524288 | xargs) |
Contributor
There was a problem hiding this comment.
Any particular reason why it is a ramdisk for HFS+ and a file for BTRFS? I don't think it matters, was just curious.
Member
Author
There was a problem hiding this comment.
No particular reason, just agent slop — I'll move it to a file if it's easy.
Member
Author
It shall not |
Merged
5 tasks
zanieb
added a commit
that referenced
this pull request
Feb 24, 2026
Fixes an regression from #18117 where executable permissions were not preserved on reflink. On Linux, the `FICLONE` ioctl only clones data blocks without preserving file metadata, so permissions must be copied separately. On macOS, `clonefile` already preserves permissions. This appears to be a well known issue: - pnpm/pnpm#8546 - https://github.com/morelj/reflink/blob/53408edf3bf3c5090b1146923f72066c7f6e9200/cloneflags.go#L6-L22 - python/cpython#81338 Closes #18181
tmeijn
pushed a commit
to tmeijn/dotfiles
that referenced
this pull request
Feb 25, 2026
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [uv](https://github.com/astral-sh/uv) | patch | `0.10.4` → `0.10.6` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>astral-sh/uv (uv)</summary> ### [`v0.10.6`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0106) [Compare Source](astral-sh/uv@0.10.5...0.10.6) Released on 2026-02-24. ##### Bug fixes - Apply lockfile marker normalization for fork markers ([#​18116](astral-sh/uv#18116)) - Fix Python version selection for scripts with a `requires-python` conflicting with `.python-version` ([#​18097](astral-sh/uv#18097)) - Preserve file permissions when using reflinks on Linux ([#​18187](astral-sh/uv#18187)) ##### Documentation - Remove verbose documentation from optional dependencies help text ([#​18180](astral-sh/uv#18180)) ### [`v0.10.5`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0105) [Compare Source](astral-sh/uv@0.10.4...0.10.5) Released on 2026-02-23. ##### Enhancements - Add hint when named index is found in a parent config file ([#​18087](astral-sh/uv#18087)) - Add warning for `uv lock --frozen` ([#​17859](astral-sh/uv#17859)) - Attempt to use reflinks by default on Linux ([#​18117](astral-sh/uv#18117)) - Fallback to hardlinks after reflink failure before copying ([#​18104](astral-sh/uv#18104)) - Filter `pylock.toml` wheels by tags and `requires-python` ([#​18081](astral-sh/uv#18081)) - Validate wheel filenames are normalized during `uv publish` ([#​17783](astral-sh/uv#17783)) - Fix message when `exclude-newer` invalidates the lock file ([#​18100](astral-sh/uv#18100)) - Change the missing files log level to debug ([#​18075](astral-sh/uv#18075)) ##### Performance - Improve performance of repeated conflicts with an extra ([#​18094](astral-sh/uv#18094)) ##### Bug fixes - Fix `--no-emit-workspace` with `--all-packages` on single-member workspaces ([#​18098](astral-sh/uv#18098)) - Fix `UV_NO_DEFAULT_GROUPS` rejecting truthy values like `1` ([#​18057](astral-sh/uv#18057)) - Fix iOS detection ([#​17973](astral-sh/uv#17973)) - Propagate project-level conflicts to package extras ([#​18096](astral-sh/uv#18096)) - Use a global build concurrency semaphore ([#​18054](astral-sh/uv#18054)) ##### Documentation - Update documentation heading for environment variable files ([#​18122](astral-sh/uv#18122)) - Fix comment about `uv export` formats ([#​17900](astral-sh/uv#17900)) - Make it clear that Windows is supported in user- and system- level configuration docs ([#​18106](astral-sh/uv#18106)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4zMS4xIiwidXBkYXRlZEluVmVyIjoiNDMuMzEuOSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6OnBhdGNoIl19-->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Copy of #17753 which GitHub auto-closed.
This adds test infrastructure for cross-device links and file systems with reflink support. In short, we create a few extra file systems on the CI runners then provide their paths to the test suite using environment variables to ensure we have coverage. If the variables are not set, the tests are skipped.