Speed up realpath on Linux and macOS#3838
Open
jakebailey wants to merge 7 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Speeds up osFS.Realpath on Linux and macOS by replacing filepath.EvalSymlinks (which does an lstat per path component) with O(1)-syscall canonicalization: open(O_PATH) + readlink(/proc/self/fd/N) on Linux and open(O_EVTONLY) + fcntl(F_GETPATH) on macOS. Both implementations probe for kernel/OS support once and fall back to EvalSymlinks when unavailable. A shared EINTR retry helper is introduced, and a deeper benchmark case is added.
Changes:
- Add
realpath_linux.gousingO_PATH+/proc/self/fd/<fd>readlink, with async.OnceValueprobe for procfs availability. - Add
realpath_darwin.gousingO_EVTONLY+fcntl(F_GETPATH), with async.OnceValueprobe forF_GETPATHsupport. - Restrict
realpath_other.goto non-Linux/non-Darwin Unix, add EINTR retry helpers ineintr_unix.go, and extendrealpath_test.gowith a deep-path benchmark and anEvalSymlinksbaseline.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/vfs/osvfs/realpath_linux.go | New Linux fast-path realpath via O_PATH and /proc/self/fd. |
| internal/vfs/osvfs/realpath_darwin.go | New macOS fast-path realpath via O_EVTONLY and fcntl(F_GETPATH). |
| internal/vfs/osvfs/realpath_other.go | Narrow build constraint so Linux/Darwin use the new specialized files. |
| internal/vfs/osvfs/eintr_unix.go | New EINTR retry helpers (ignoringEINTR, ignoringEINTR2) for non-Windows builds. |
| internal/vfs/osvfs/realpath_test.go | Add deep and deep_evalSymlinks benchmarks to demonstrate scaling. |
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.
On Linux, we can open a file with
O_PATHto ask it to be opened only for path resolution, then check/proc/self/fd/<fd>for the finalized path in one go. This avoidsEvalSymlinksentirely, greatly speeding up realpath.On
macOS, we can do a similar thing usingfcntl(F_GETPATH). This is not that drastic, but is still faster for unlinked files, the common case.Other OSs might have something like this, but now we have special cases for Windows, Linux, and macOS, which is most everyone.