vfs: Generate IN_MODIFY on open(O_TRUNC) for existing files#12854
vfs: Generate IN_MODIFY on open(O_TRUNC) for existing files#12854tanyifeng wants to merge 1 commit intogoogle:masterfrom
Conversation
|
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. |
e17b4fb to
125159b
Compare
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>
125159b to
72916c6
Compare
| // 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 |
There was a problem hiding this comment.
Move this to pkg/abi/linux/file.go
| // 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 |
There was a problem hiding this comment.
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
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.