gofer: Take refs when adopting a cached endpoint-bearing inode - #14093
Open
copybara-service[bot] wants to merge 1 commit into
Open
gofer: Take refs when adopting a cached endpoint-bearing inode#14093copybara-service[bot] wants to merge 1 commit into
copybara-service[bot] wants to merge 1 commit into
Conversation
copybara-service
Bot
force-pushed
the
test/cl963620436
branch
from
August 12, 2026 23:34
c27e776 to
eaa2d8a
Compare
When an AF_UNIX socket is bound to a path, the resulting BoundEndpoint is stored on the gofer inode, and other processes reach it by path: they walk to the dentry, then pull the endpoint off its inode and connect. Crucially, a bound socket stays connectable even when no file descriptor is holding that path open. The gofer refcounting invariant is: "An additional reference is held on all synthetic dentries, and on all dentries for which endpoint is non-nil, until they are unlinked or invalidated." This purpose of this invariant is for a host-backed bound UDS must stay resolvable by path even when no FD holds it. A gofer dentry at refs == 0 is eligible for reclaim; reclaiming it tears down the inode and drops the HostBoundEndpoint (and its host FD). So the filesystem pins every endpoint- bearing dentry with one extra ref, held from bind until the name goes away. This extra ref is dropped unconditionally, guarded only by `endpoint != nil` in many places: unlinkAt, RenameAt, revalidation/invalidation, filesystem teardown etc. (These drop paths assume that the invariant holds.) To establish the invariant the extra ref is taken in the bind paths sure, but we were missing a reference increment for a dentry that later comes to point at the same endpoint-bearing inode. This can happen either due to a hard link or another walk that lands on the same inode. PiperOrigin-RevId: 963620436
copybara-service
Bot
force-pushed
the
test/cl963620436
branch
from
August 13, 2026 22:37
eaa2d8a to
62a989b
Compare
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.
gofer: Take refs when adopting a cached endpoint-bearing inode
When an AF_UNIX socket is bound to a path, the resulting BoundEndpoint is
stored on the gofer inode, and other processes reach it by path: they walk
to the dentry, then pull the endpoint off its inode and connect. Crucially,
a bound socket stays connectable even when no file descriptor is holding
that path open.
The gofer refcounting invariant is: "An additional reference is held on all
synthetic dentries, and on all dentries for which endpoint is non-nil, until
they are unlinked or invalidated."
This purpose of this invariant is for a host-backed bound UDS must stay
resolvable by path even when no FD holds it. A gofer dentry at refs == 0 is
eligible for reclaim; reclaiming it tears down the inode and drops the
HostBoundEndpoint (and its host FD). So the filesystem pins every endpoint-
bearing dentry with one extra ref, held from bind until the name goes away.
This extra ref is dropped unconditionally, guarded only by
endpoint != nilin many places: unlinkAt, RenameAt, revalidation/invalidation, filesystem
teardown etc. (These drop paths assume that the invariant holds.)
To establish the invariant the extra ref is taken in the bind paths sure, but
we were missing a reference increment for a dentry that later comes to point
at the same endpoint-bearing inode. This can happen either due to a hard link
or another walk that lands on the same inode.