Skip to content

gofer: Take refs when adopting a cached endpoint-bearing inode - #14093

Open
copybara-service[bot] wants to merge 1 commit into
masterfrom
test/cl963620436
Open

gofer: Take refs when adopting a cached endpoint-bearing inode#14093
copybara-service[bot] wants to merge 1 commit into
masterfrom
test/cl963620436

Conversation

@copybara-service

@copybara-service copybara-service Bot commented Aug 12, 2026

Copy link
Copy Markdown

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 != 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.

@copybara-service copybara-service Bot added the exported Issue was exported automatically label Aug 12, 2026
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 copybara-service Bot changed the title gofer: take reference when adopting a cached endpoint-bearing inode gofer: Take refs when adopting a cached endpoint-bearing inode Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

exported Issue was exported automatically

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant