Skip to content

vfs: Generate IN_MODIFY on open(O_TRUNC) for existing files#12854

Open
tanyifeng wants to merge 1 commit intogoogle:masterfrom
tanyifeng:vfs-add-inmodify
Open

vfs: Generate IN_MODIFY on open(O_TRUNC) for existing files#12854
tanyifeng wants to merge 1 commit intogoogle:masterfrom
tanyifeng:vfs-add-inmodify

Conversation

@tanyifeng
Copy link
Copy Markdown
Contributor

@tanyifeng tanyifeng commented Apr 2, 2026

Linux's handle_truncate() emits IN_MODIFY before IN_OPEN when an existing file is opened with O_TRUNC. gVisor only generated IN_OPEN, breaking programs like syncthing that rely on inotify to detect file truncation via open().

Add an fmodeFlags field (with FMODE_CREATED) to FileDescription so VirtualFilesystem.OpenAt() can distinguish newly created files from existing ones and emit IN_MODIFY accordingly.

@aaltinaydev
Copy link
Copy Markdown

Do we need to update other openat functions as well? For example:https://github.com/google/gvisor/blob/master/pkg/sentry/fsimpl/erofs/filesystem.go#L219

@ayushr2
Copy link
Copy Markdown
Collaborator

ayushr2 commented Apr 3, 2026

Do we need to update other openat functions as well? For example:https://github.com/google/gvisor/blob/master/pkg/sentry/fsimpl/erofs/filesystem.go#L219

@aaltinaydev EROFS is a read-only filesystem and does not support writable operations like O_TRUNC.

Linux's handle_truncate() emits IN_MODIFY before IN_OPEN when an
existing file is opened with O_TRUNC. gVisor only generated IN_OPEN,
breaking programs like syncthing that rely on inotify to detect
file truncation via open().

Add an fmodeFlags field (with FMODE_CREATED) to FileDescription so
VirtualFilesystem.OpenAt() can distinguish newly created files from
existing ones and emit IN_MODIFY accordingly.

Signed-off-by: Tan Yifeng <yiftan@tencent.com>
Comment on lines +104 to +108
// FMODE_CREATED is set when a file is newly created by an open operation
// (O_CREAT and the file did not already exist). It is used by
// VirtualFilesystem.OpenAt() to avoid generating a spurious IN_MODIFY inotify
// event for O_TRUNC on newly created files.
const FMODE_CREATED = 0x100000
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this to pkg/abi/linux/file.go

Comment on lines 84 to 95
// readable is MayReadFileWithOpenFlags(statusFlags). readable is
// immutable.
//
// readable is analogous to Linux's FMODE_READ.
readable bool

// writable is MayWriteFileWithOpenFlags(statusFlags). If writable is true,
// the FileDescription holds a write count on vd.mount. writable is
// immutable.
//
// writable is analogous to Linux's FMODE_WRITE.
writable bool
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about it more, these fields should be folded into fmodeFlags. In Linux, they are represented as FMODE_READ and FMODE_WRITE (as the comments say).

Secondly, fmodeFlags should be immutable. fmodeFlags is really only set on FD creation. After initialization, fmodeFlags should be considered immutable. Add a precondition on SetCreated() that it should only be used during FD creation and initialization phase. Querying fmodeFlags (for IsCreated(), IsReadable() and IsWritable()) should be lockless as the field is immutable at that point (and called on hot paths). In Linux too this field is immutable after initialization (AFAICT) and is used on hot paths, see comment on f_mode:

/**
 * struct file - Represents a file
 * @f_lock: Protects f_ep, f_flags. Must not be taken from IRQ context.
 * @f_mode: FMODE_* flags often used in hotpaths
 * @f_op: file operations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants