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

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 2 times, most recently from 1efd172 to 8fad46f Compare August 1, 2026 06:38
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 -> 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).
- 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.
- Guard DELETE_SELF on hardlink unlink/rename-over: only emit when
  i_nlink reaches 0, matching Linux fsnotify_link_count() semantics.
- Fix MountFSInode downcast: MountFSInode::as_any_ref() returns the
  inner inode's Any, so downcast_ref::<MountFSInode>() always fails.
  Use downcast_arc instead so parent resolution works for child
  content event delivery.
- TOTAL_WATCHES counter: avoid double-decrement / double-increment.

Test: user/apps/tests/dunitest/suites/normal/inotify_dir_watch.cc
covers directory-watch child content events and self-watch MODIFY.

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