Skip to content

feat(fs): implement inotify filesystem event notification - #2164

Open
sparkzky wants to merge 1 commit into
DragonOS-Community:masterfrom
sparkzky:feat/inotify
Open

feat(fs): implement inotify filesystem event notification#2164
sparkzky wants to merge 1 commit into
DragonOS-Community:masterfrom
sparkzky:feat/inotify

Conversation

@sparkzky

@sparkzky sparkzky commented Jul 31, 2026

Copy link
Copy Markdown
Member

Summary

Implements inotify (issue #2151): filesystem event notification with inotify_init1 / inotify_add_watch / inotify_rm_watch / read, the full standard event set, epoll integration, and exact inotify_event ABI.

Design doc: docs/kernel/filesystem/inotify.md. Behavior targets Linux 6.6.

Architecture (3 layers)

  • fsnotify unified dispatch layer (fs/notify/-style): global inode_id -> Weak<mark> index, TOTAL_WATCHES atomic fast-path (zero cost when no watches), lock-family separation (global index lock / events lock / wd lock never nested). Hooks fire only after success and never alter syscall return values.
  • inotify device (inotify.rs): InotifyInode implements IndexNode + PollableInode, epoll-integrated via LockedEPItemLinkedList, exact inotify_event layout (name field aligned to sizeof(inotify_event)=16, matching the Linux 6.6 ABI).
  • VFS write-path hooks in the syscall-core layer (vcore/open/rename_utils/...), not per-filesystem: a single anchor covers ext4/tmpfs/overlayfs/fuse.

What this PR adds beyond the initial implementation

The initial implementation was put through a 3-way adversarial review (independent reviewers) + independent verification. This PR includes both the feature and the resulting fixes:

Directory watches now receive child content events (the primary inotify use case, e.g. inotifywait -m /dir). Previously only namespace events (create/delete/move) reached directory watches; IN_MODIFY/ACCESS/OPEN/CLOSE on children were silently dropped. Resolved by snapshotting the parent dir + child name once at File construction (gated by has_any_watch for zero cost when unused) and routing content events to both the parent (with name) and self watch. This also makes IN_EXCL_UNLINK effective.

Other review fixes (all verified):

  • TOTAL_WATCHES double-count on add_watch (broke the no-watch fast path).
  • add_watch TOCTOU: concurrent same-inode adds created duplicate marks.
  • IN_EXCL_UNLINK polarity was inverted.
  • fallocate: restored the offset+len overflow guard removed during the IN_MODIFY refactor.
  • rename overwriting an existing target now emits IN_DELETE/IN_DELETE_SELF (was a ghost-watch leak).
  • RENAME_EXCHANGE now emits the full 4 namespace events + 2 MOVE_SELF with two cookies.

Testing

  • dunitest regression coverage: normal/inotify_dir_watch (directory-watch child content events + self-watch sanity), added to the whitelist so CI runs it.
  • Kernel compiles clean (make kernel).
  • Known narrow limitations (documented in docs/impl-notes/): rename-after-open yields a stale parent snapshot (EXCL_UNLINK covers unlink); IN_ATTRIB-to-parent via fd-based setattr is not yet wired; unmount does not emit IN_UNMOUNT (watch reclaims on fd close).

Checklist

  • make kernel compiles
  • dunitest build + runtime (to be run on a test machine)

@github-actions github-actions Bot added the enhancement New feature or request label Jul 31, 2026
@fslongjin

Copy link
Copy Markdown
Member

needs to rebase

@sparkzky
sparkzky force-pushed the feat/inotify branch 3 times, most recently from 8fad46f to 05ce40d Compare August 1, 2026 07:01
@fslongjin

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05ce40d4de

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread kernel/src/filesystem/fsnotify/mod.rs Outdated
Comment thread kernel/src/filesystem/vfs/file.rs Outdated
Comment thread kernel/src/filesystem/fsnotify/mod.rs Outdated
Comment thread kernel/src/filesystem/vfs/vcore.rs Outdated
Comment thread kernel/src/filesystem/vfs/syscall/rename_utils.rs
Comment thread kernel/src/filesystem/inotify.rs
Comment thread kernel/src/filesystem/inotify.rs Outdated
Comment thread kernel/src/filesystem/vfs/file.rs Outdated
Comment thread kernel/src/filesystem/inotify.rs
Comment thread kernel/src/filesystem/vfs/syscall/rename_utils.rs
sparkzky added a commit to sparkzky/DragonOS that referenced this pull request Aug 8, 2026
…5 P1 + 4 P2)

P1 fixes:
- Composite mark index key (inode_id, dev_id): prevents FUSE cross-mount
  event leakage when multiple mounts reuse same inode number.
- Remove has_any_watch() gate on File::inotify_parent resolution: watches
  added after open now correctly receive content events.
- Move inode-death (DELETE_SELF/UNMOUNT) destroy before mask subscription
  filter: prevents watch leak when watch doesn't subscribe to the event.
- Cache nlinks before unlink/rename-over: avoids FUSE GETATTR failure
  after namespace change; uses pre-operation link count for DELETE_SELF.
- Rename-over checks displaced nlinks: multiple hardlinks survive.

P2 fixes:
- Sync IN_ONESHOT field on IN_MASK_ADD (OR semantics).
- Dynamic O_NONBLOCK: fcntl(F_SETFL) now works on inotify fds.
- EOF reads (len==0) no longer deliver IN_ACCESS.
- Reject mask==0 and IN_MASK_ADD|IN_MASK_CREATE as EINVAL.
- Skip MOVED events on no-op rename (same dir + same name).

Verified: make kernel clean, inotify_dir_watch 2/2 PASS, fuse_core 6/6 PASS.
Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
Implements inotify (issue DragonOS-Community#2151): the fsnotify core notification layer,
the inotify pseudo-device, 4 syscalls (init/init1/add_watch/rm_watch),
and VFS write-path hooks for all standard events (create/delete/move/
modify/access/close/attrib/self events).

Architecture:
- fsnotify/ unified dispatch layer: global (inode_id, dev_id) index,
  TOTAL_WATCHES atomic fast-path (zero cost when no watches), lock-family
  separation (global index lock / events lock / wd lock never nested).
- inotify.rs device: InotifyInode implements IndexNode + PollableInode,
  epoll-integrated via LockedEPItemLinkedList, exact inotify_event layout
  (name field aligned to sizeof(inotify_event)=16, matching Linux ABI).
- VFS hooks placed in syscall-core layer (vcore/open/rename_utils/...),
  NOT per-filesystem: single anchor covers ext4/tmpfs/overlayfs/fuse.
  Hooks fire only after success and never alter syscall return values.

Review fixes incorporated:
- Directory watches receive child content events (issue B): IN_MODIFY/
  ACCESS/OPEN/CLOSE delivered to parent dir watch with child name.
  MountFSInode::as_any_ref() returns the inner inode's Any, so use
  downcast_arc instead of downcast_ref for parent resolution.
- Guard DELETE_SELF on hardlink unlink/rename-over: only emit when
  i_nlink reaches 0, matching Linux fsnotify_link_count() semantics.
- Composite mark index key (inode_id, dev_id): prevents FUSE cross-mount
  event leakage when multiple mounts reuse same inode number.
- Remove has_any_watch() gate on File::inotify_parent resolution so
  watches added after open receive content events.
- Tolerate metadata failure after unlink/rename-over (FUSE GETATTR can
  return ENOENT); cache nlinks before the namespace operation.
- SYS_INOTIFY_INIT only registered on x86_64 (generic syscall ABI uses
  inotify_init1); riscv64/loongarch64 lack the legacy init syscall.
- Skip MOVED events on no-op rename; EOF reads no longer deliver
  IN_ACCESS; reject mask==0 and IN_MASK_ADD|IN_MASK_CREATE.

Test: dunitest inotify_dir_watch (2 tests) + inotify_events (6 tests)
covering content/namespace/self events, multi-instance, and poll.

Design doc: docs/kernel/filesystem/inotify.md

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants