git: 2e5f492fe30b - stable/14 - inotify: Add man pages for the new syscalls and for VOP_INOTIFY

Mark Johnston <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a7353cd.441e7.4fa51e2__6927.29310119233$1785943133$gmane$org@gitrepo.freebsd.org>
The branch stable/14 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=2e5f492fe30b329900dd64c8bbb52cf3d14c37f9

commit 2e5f492fe30b329900dd64c8bbb52cf3d14c37f9
Author:     Mark Johnston <[email protected]>
AuthorDate: 2025-07-03 20:02:21 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2026-08-05 15:15:15 +0000

    inotify: Add man pages for the new syscalls and for VOP_INOTIFY
    
    Reviewed by:    kib
    MFC after:      3 months
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D50315
    
    (cherry picked from commit 5202cfcf93b19b39f3d2bf80e73a8ca94d7fffd1)
---
 lib/libc/sys/Makefile.inc    |   6 +
 lib/libc/sys/inotify.2       | 379 +++++++++++++++++++++++++++++++++++++++++++
 share/man/man9/Makefile      |   2 +
 share/man/man9/VOP_INOTIFY.9 |  60 +++++++
 4 files changed, 447 insertions(+)

diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index ebcb69d283f6..8b58cbed161f 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -223,6 +223,7 @@ MAN+=	abort2.2 \
 	getsockopt.2 \
 	gettimeofday.2 \
 	getuid.2 \
+	inotify.2 \
 	intro.2 \
 	ioctl.2 \
 	issetugid.2 \
@@ -437,6 +438,11 @@ MLINKS+=getrlimit.2 setrlimit.2
 MLINKS+=getsockopt.2 setsockopt.2
 MLINKS+=gettimeofday.2 settimeofday.2
 MLINKS+=getuid.2 geteuid.2
+MLINKS+=inotify.2 inotify_init.2 \
+	inotify.2 inotify_init1.2 \
+	inotify.2 inotify_add_watch.2 \
+	inotify.2 inotify_add_watch_at.2 \
+	inotify.2 inotify_rm_watch.2
 MLINKS+=intro.2 errno.2
 MLINKS+=jail.2 jail_attach.2 \
 	jail.2 jail_get.2 \
diff --git a/lib/libc/sys/inotify.2 b/lib/libc/sys/inotify.2
new file mode 100644
index 000000000000..f94509d6f59e
--- /dev/null
+++ b/lib/libc/sys/inotify.2
@@ -0,0 +1,379 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2025 Klara, Inc.
+.\"
+.Dd May 19, 2025
+.Dt INOTIFY 2
+.Os
+.Sh NAME
+.Nm inotify_init ,
+.Nm inotify_init1 ,
+.Nm inotify_add_watch ,
+.Nm inotify_add_watch_at ,
+.Nm inotify_rm_watch
+.Nd monitor file system events
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/inotify.h
+.Ft int
+.Fo inotify_init
+.Fc
+.Ft int
+.Fo inotify_init1
+.Fa "int flags"
+.Fc
+.Ft int
+.Fo inotify_add_watch
+.Fa "int fd"
+.Fa "const char *pathname"
+.Fa "uint32_t mask"
+.Fc
+.Ft int
+.Fo inotify_add_watch_at
+.Fa "int fd"
+.Fa "int dfd"
+.Fa "const char *pathname"
+.Fa "uint32_t mask"
+.Fc
+.Ft int
+.Fo inotify_rm_watch
+.Fa "int fd"
+.Fa "uint32_t wd"
+.Fc
+.Bd -literal
+struct inotify_event {
+	int wd;			/* Watch descriptor */
+	uint32_t mask;		/* Event and flags */
+	uint32_t cookie;	/* Unique ID which links rename events */
+	uint32_t len;		/* Name field size, including nul bytes */
+	char name[0];		/* Filename (nul-terminated) */
+};
+.Ed
+.Sh DESCRIPTION
+The inotify system calls provide an interface to monitor file system events.
+They aim to be compatible with the Linux inotify interface.
+The provided functionality is similar to the
+.Dv EVFILT_VNODE
+filter of the
+.Xr kevent 2
+system call, but further allows monitoring of a directory without needing to
+open each object in that directory.
+This avoids races and reduces the number of file descriptors needed to monitor
+a large file hierarchy.
+.Pp
+inotify allows one or more file system objects, generally files or directories,
+to be watched for events, such as file open or close.
+Watched objects are associated with a file descriptor returned
+by
+.Fn inotify_init
+or
+.Fn inotify_init1 .
+When an event occurs, a record describing the event becomes available for
+reading from the inotify file descriptor.
+Each inotify descriptor thus refers to a queue of events waiting to be read.
+inotify descriptors are inherited across
+.Xr fork 2
+calls and may be passed to other processes via
+.Xr unix 4
+sockets.
+.Pp
+The
+.Fn inotify_init1
+system call accepts two flags.
+The
+.Dv IN_NONBLOCK
+flag causes the inotify descriptor to be opened in non-blocking mode, such that
+.Xr read 2
+calls will not block if no records are available to consume, and will instead
+return
+.Er EWOULDBLOCK .
+The
+.Dv IN_CLOEXEC
+flag causes the inotify descriptor to be closed automatically when
+.Xr execve 2
+is called.
+.Pp
+To watch a file or directory, the
+.Fn inotify_add_watch
+or
+.Fn inotify_add_watch_at
+system calls must be used.
+They take a path and a mask of events to watch for, and return a
+.Dq watch descriptor ,
+a non-negative integer which uniquely identifies the watched object within the
+inotify descriptor.
+.Pp
+The
+.Fn inotify_rm_watch
+system call removes a watch from an inotify descriptor.
+.Pp
+When watching a directory, objects within the directory are monitored for events
+as well as the directory itself.
+A record describing an inotify event consists of a
+.Dq struct inotify_event
+followed by the name of the object in the directory being watched.
+If the watched object itself generates an event, no name is present.
+Extra nul bytes may follow the file name in order to provide alignment for a
+subsequent record.
+.Pp
+The following events are defined:
+.Bl -tag -width IN_CLOSE_NOWRITE
+.It Dv IN_ACCESS
+A file's contents were accessed, e.g., by
+.Xr read 2
+.Xr copy_file_range 2 ,
+.Xr sendfile 2 ,
+or
+.Xr getdirentries 2 .
+.It Dv IN_ATTRIB
+A file's metadata was changed, e.g., by
+.Xr chmod 2
+or
+.Xr unlink 2 .
+.It Dv IN_CLOSE_WRITE
+A file that was previously opened for writing was closed.
+.It Dv IN_CLOSE_NOWRITE
+A file that was previously opened read-only was closed.
+.It Dv IN_CREATE
+A file within a watched directory was created, e.g., by
+.Xr open 2 ,
+.Xr mkdir 2 ,
+.Xr symlink 2 ,
+.Xr mknod 2 ,
+or
+.Xr bind 2 .
+.It Dv IN_DELETE
+A file or directory within a watched directory was removed.
+.It Dv IN_DELETE_SELF
+The watched file or directory itself was deleted.
+This event is generated only when the link count of the file drops
+to zero.
+.It Dv IN_MODIFY
+A file's contents were modified, e.g., by
+.Xr write 2
+or
+.Xr copy_file_range 2 .
+.It Dv IN_MOVE_SELF
+The watched file or directory itself was renamed.
+.It Dv IN_MOVED_FROM
+A file or directory was moved from a watched directory.
+.It Dv IN_MOVED_TO
+A file or directory was moved into a watched directory.
+A
+.Xr rename 2
+call thus may generate two events, one for the old name and one for the new
+name.
+These are linked together by the
+.Ar cookie
+field in the inotify record, which can be compared to link the two records
+to the same event.
+.It Dv IN_OPEN
+A file was opened.
+.El
+.Pp
+Some additional flags may be set in inotify event records:
+.Bl -tag -width IN_Q_OVERFLOW
+.It Dv IN_IGNORED
+When a watch is removed from a file, for example because it was created with the
+.Dv IN_ONESHOT
+flag, the file was deleted, or the watch was explicitly removed with
+.Xr inotify_rm_watch 2 ,
+an event with this mask is generated to indicate that the watch will not
+generate any more events.
+Once this event is generated, the watch is automatically removed, and in
+particular should not be removed manually with
+.Xr inotify_rm_watch 2 .
+.It Dv IN_ISDIR
+When the subject of an event is a directory, this flag is set in the
+.Ar mask
+.It Dv IN_Q_OVERFLOW
+One or more events were dropped, for example because of a kernel memory allocation
+failure or because the event queue size hit a limit.
+.It Dv IN_UNMOUNT
+The filesystem containing the watched object was unmounted.
+.El
+.Pp
+A number of flags may also be specified in the
+.Ar mask
+given to
+.Fn inotify_add_watch
+and
+.Fn inotify_add_watch_at :
+.Bl -tag -width IN_DONT_FOLLOW
+.It Dv IN_DONT_FOLLOW
+If
+.Ar pathname
+is a symbolic link, do not follow it.
+.It Dv IN_EXCL_UNLINK
+This currently has no effect, see the
+.Sx BUGS
+section.
+.In Dv IN_MASK_ADD
+When adding a watch to an object, and that object is already watched by the
+same inotify descriptor, by default the mask of the existing watch is
+overwritten.
+When
+.Dv IN_MASK_ADD
+is specified, the mask of the existing watch is instead logically ORed with
+the new mask.
+.In Dv IN_MASK_CREATE
+When
+.Fn inotify_add watch
+is used to add a watch to an object,
+.Dv IN_MASK_CREATE
+is specified, and that object is already watched by the same inotify descriptor,
+return an error instead of updating the existing watch.
+.In Dv IN_ONESHOT
+Monitor the object for a single event, after which the watch is automatically
+removed.
+As part of removal, a
+.Dv IN_IGNORED
+event is generated.
+.In Dv IN_ONLYDIR
+When creating a watch, fail with
+.Er ENOTDIR
+if the path does not refer to a directory.
+.El
+.Sh SYSCTL VARIABLES
+The following variables are available as both
+.Xr sysctl 8
+variables and
+.Xr loader 8
+tunables:
+.Bl -tag -width 15
+.It Va vfs.inotify.max_events
+The maximum number of inotify records that can be queued for a single
+inotify descriptor.
+Records in excess of this limit are discarded, and a single event with
+mask equal to
+.Dv IN_Q_OVERFLOW
+will be present in the queue.
+.It Va vfs.inotify.max_user_instances
+The maximum number of inotify descriptors that can be created by a single
+user.
+.It Va vfs.inotify.max_user_watches
+The maximum number of inotify watches per user.
+.El
+.Sh EXAMPLES
+See the example program in
+.Pa /usr/share/examples/inotify/inotify.c .
+.Sh ERRORS
+The
+.Fn inotify_init
+and
+.Fn inotify_init1
+functions will fail if:
+.Bl -tag -width Er
+.It Bq Er ENFILE
+The system limit on the total number of open files has been reached.
+.It Bq Er EMFILE
+A per-process limit on the number of open files has been reached.
+.It Bq Er EMFILE
+The system limit on the number of inotify descriptors has been reached.
+.It Bq Er EINVAL
+An unrecognized flag was passed to
+.Fn inotify_init1 .
+.El
+.Pp
+The
+.Fn inotify_add_watch
+and
+.Fn inotify_add_watch_at
+system calls will fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Ar fd
+parameter is not a valid file descriptor.
+.It Bq Er EINVAL
+The
+.Ar fd
+parameter is not an inotify descriptor.
+.It Bq Er EINVAL
+The
+.Ar mask
+parameter does not specify an event, or
+the
+.Dv IN_MASK_CREATE
+and
+.Dv IN_MASK_ADD
+flags are both set, or an unrecognized flag was passed.
+.It Bq Er ENOTDIR
+The
+.Ar pathname
+parameter refers to a file that is not a directory, and the
+.Dv IN_ONLYDIR
+flag was specified.
+.It Bq Er ENOSPC
+The per-user limit on the total number of inotify watches has been reached.
+.It Bq Er ECAPMODE
+The process is in capability mode and
+.Fn inotify_add_watch
+was called, or
+.Fn inotify_add_watch_at
+was called with
+.Dv AT_FDCWD
+as the directory file descriptor
+.Ar dfd .
+.It Bq Er ENOTCAPABLE
+The process is in capability mode and
+.Ar pathname
+contains a
+.Dq ..
+component leading to a directory outside the directory hierarchy specified
+by
+.Ar dfd .
+.El
+.Pp
+The
+.Fn inotify_rm_watch
+system call will fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Ar fd
+parameter is not a valid file descriptor.
+.It Bq Er EINVAL
+The
+.Ar fd
+parameter is not an inotify descriptor.
+.It Bq Er EINVAL
+The
+.Ar wd
+parameter is not a valid watch descriptor.
+.El
+.Sh SEE ALSO
+.Xr kevent 2 ,
+.Xr capsicum 4
+.Sh STANDARDS
+The
+.Nm
+interface originates from Linux and is non-standard.
+This implementation aims to be compatible with that of Linux and is based
+on the documentation available at
+.Pa https://man7.org/linux/man-pages/man7/inotify.7.html .
+.Sh HISTORY
+The inotify system calls first appeared in
+.Fx 15.0 .
+.Sh BUGS
+If a file in a watched directory has multiple hard links,
+an access via any hard link for that file will generate an event, even
+if the accessed link belongs to an unwatched directory.
+This is not the case for the Linux implementation, where only accesses
+via the hard link in the watched directory will generate an event.
+.Pp
+If a watched directory contains multiple hard links of a file, an event
+on one of the hard links will generate an inotify record for each link
+in the directory.
+.Pp
+When a file is unlinked, no more events will be generated for that file,
+even if it continues to be accessed.
+By default, the Linux implementation will continue to generate events in
+this case.
+Thus, the
+.Fx
+implementation behaves as though
+.Dv IN_EXCL_UNLINK
+is always set.
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index aad3025b6fa0..9d7585ffc2ee 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -438,6 +438,7 @@ MAN=	accept_filter.9 \
 	VOP_GETEXTATTR.9 \
 	VOP_GETPAGES.9 \
 	VOP_INACTIVE.9 \
+	VOP_INOTIFY.9 \
 	VOP_IOCTL.9 \
 	VOP_LINK.9 \
 	VOP_LISTEXTATTR.9 \
@@ -2475,6 +2476,7 @@ MLINKS+=VOP_CREATE.9 VOP_MKDIR.9 \
 MLINKS+=VOP_FSYNC.9 VOP_FDATASYNC.9
 MLINKS+=VOP_GETPAGES.9 VOP_PUTPAGES.9
 MLINKS+=VOP_INACTIVE.9 VOP_RECLAIM.9
+MLINKS+=VOP_INOTIFY.9 VOP_INOTIFY_ADD_WATCH.9
 MLINKS+=VOP_LOCK.9 vn_lock.9 \
 	VOP_LOCK.9 VOP_ISLOCKED.9 \
 	VOP_LOCK.9 VOP_UNLOCK.9
diff --git a/share/man/man9/VOP_INOTIFY.9 b/share/man/man9/VOP_INOTIFY.9
new file mode 100644
index 000000000000..43b644682153
--- /dev/null
+++ b/share/man/man9/VOP_INOTIFY.9
@@ -0,0 +1,60 @@
+.\"-
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2025 Klara, Inc.
+.\"
+.Dd May 27, 2025
+.Dt VOP_INOTIFY 9
+.Os
+.Sh NAME
+.Nm VOP_INOTIFY
+.Nd vnode inotify interface
+.Sh SYNOPSIS
+.In sys/param.h
+.In sys/vnode.h
+.Ft int
+.Fo VOP_INOTIFY
+.Fa struct vnode *vp
+.Fa struct vnode *dvp
+.Fa struct componentname *cnp
+.Fa int event
+.Fa uint32_t cookie
+.Fc
+.Ft int
+.Fo VOP_INOTIFY_ADD_WATCH
+.Fa struct vnode *vp
+.Fa struct inotify_softc *sc
+.Fa uint32_t mask
+.Fa uint32_t *wdp
+.Fa struct thread *td
+.Fc
+.Sh DESCRIPTION
+The
+.Fn VOP_INOTIFY
+operation notifies the
+.Xr inotify 2
+subsystem of a file system event on a vnode.
+The
+.Fa dvp
+and
+.Fa cnp
+arguments are optional and are only used to obtain a file name for the event.
+If they are omitted, the inotify subsystem will use the file name cache to
+find a name for the vnode, but this is more expensive.
+.Pp
+The
+.Fn VOP_INOTIFY_ADD_WATCH
+operation is for internal use by the inotify subsystem to add a watch to a
+vnode.
+.Sh LOCKS
+The
+.Fn VOP_INOTIFY
+operation does not assume any particular vnode lock state.
+The
+.Fn VOP_INOTIFY_ADD_WATCH
+operation should be called with the vnode locked.
+.Sh RETURN VALUES
+Zero is returned on success, otherwise an error code is returned.
+.Sh SEE ALSO
+.Xr inotify 2 ,
+.Xr vnode 9
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.