From nobody Wed Aug 5 15:16:36 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hFYsc70B3z6nQV2 for ; Wed, 05 Aug 2026 15:16:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hFYsc4vl0z3vw7 for ; Wed, 05 Aug 2026 15:16:36 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785942996; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=FQlMyIPUeCcoUgaXKMrFj+TMmrWZ6f9dj0umwGe4UtQ=; b=HxuMH24IcmB4J/AKxI44WM27vDJ5mJVOCYtKBXInqyJdsJj0P6H3Mq0eeKYSRgpeqb2BPM 9aAw1P5Tr5sn3P6jlDOZCV0yVJAwp97MGxYj6/6rR3JcMgmtpdusk6xkg6j8eDIgecltie sNXfCRgMsp+o/thc1pbDJt/kf9GNa/FqjPjdM3wvvNJlA37/gzEQS1YcigV+QmvE2XxGGq xhbNhPUTqFi0ja7uJ5wFoJ8d3IBF5A+QG0QhwBsnzCK2xzs9xTpdJE1gxLbKTiMOhbf90H m38zJHZ2bw/F1XpH2IcD/QELkuelMpZ+wpxV9AAn5UCRdb3NyDxkxs5MJDQR5A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785942996; a=rsa-sha256; cv=none; b=YT2hAo4Oow26cZxSHOeZGQVUO75grJ/o4gxVbH1OZG/MQH8XOCnL+Ru9TZSu3muCwp7dF2 7asOJSnYnUcI1kmEP0dxuIAsvKSNu4CYnKCndDYHluMlxYgiWrU8UH3bMjRrowdCIZip8q 5AKYci1mUop9LdUyCGfy3c16uPrmDr2RbUqV/EFWMhW4V4YlnFlDrvuJpWUkQhPmL56Gv6 69HQoWLVnZN7A23d23f9Q6qok9bG04Z7UQ+iDHi7HtoUE0h+eipOnvNl/y1umyLPRMry6y US4e90HN7ivCGFyXWBX4aZl+lrN8OSFIYIe32TaJwMDJgH5GczPAXJ0zKdxuOw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785942996; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=FQlMyIPUeCcoUgaXKMrFj+TMmrWZ6f9dj0umwGe4UtQ=; b=am4/2k0Nfx48Sk4CBGePQZgJS4T6NSW+VvFvvStHKOzrH8r6ozVezXYWqoKTLY4nnOd64U zKGpRdn2XKJZCKNY2THj30dawIW5KDfwOpLVNIP6l0u/wiM+DAZsqSjEw5o6eGamj+jJNx nAcT+OBZPm73+YmbiP2BNcFZf9HsT4Bl/B13+7M51omgzYYo9rLmW+emJT4naNtS1TDnxt r2PgScoQKvU5i1kGCWrPoej2oGb9vjIOh3WOuCQ+pjLkJ2t4d7b4cX6EytDVK6qRhLHQhd 1s2Dp4jwZW+Sw8XzxtQurMUfvid2yQO0cQtEP9FWGSupeNDrYC+gLlGsNpGOXg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hFYsc3vrjzgHd for ; Wed, 05 Aug 2026 15:16:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 45e2e by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 05 Aug 2026 15:16:36 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 64a20dd7034e - stable/14 - linux: Add inotify support List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 64a20dd7034ed6bd46e57bd143d8cc1d4d77f797 Auto-Submitted: auto-generated Date: Wed, 05 Aug 2026 15:16:36 +0000 Message-Id: <6a7353d4.45e2e.17fdc7c5@gitrepo.freebsd.org> The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=64a20dd7034ed6bd46e57bd143d8cc1d4d77f797 commit 64a20dd7034ed6bd46e57bd143d8cc1d4d77f797 Author: Mark Johnston AuthorDate: 2025-06-06 13:25:09 +0000 Commit: Mark Johnston CommitDate: 2026-08-05 15:15:15 +0000 linux: Add inotify support Implement the Linux inotify system calls using the native implementation in vfs_inotify.c. PR: 240874 Reviewed by: brooks MFC after: 3 months Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D50761 (cherry picked from commit 3965de642c29d831649c8307203303de560d721a) --- sys/amd64/linux/syscalls.master | 11 +++- sys/amd64/linux32/syscalls.master | 15 ++++- sys/arm64/linux/syscalls.master | 11 +++- sys/compat/linux/linux_dummy.c | 4 -- sys/compat/linux/linux_file.c | 121 ++++++++++++++++++++++++++++++++++++++ sys/compat/linux/linux_file.h | 32 ++++++++++ sys/i386/linux/syscalls.master | 15 ++++- sys/kern/vfs_inotify.c | 4 +- sys/sys/inotify.h | 4 ++ sys/x86/linux/linux_dummy_x86.c | 2 - 10 files changed, 201 insertions(+), 18 deletions(-) diff --git a/sys/amd64/linux/syscalls.master b/sys/amd64/linux/syscalls.master index 8e12a539b87f..d7048823b84c 100644 --- a/sys/amd64/linux/syscalls.master +++ b/sys/amd64/linux/syscalls.master @@ -1477,10 +1477,17 @@ int linux_inotify_init(void); } 254 AUE_NULL STD { - int linux_inotify_add_watch(void); + int linux_inotify_add_watch( + l_int fd, + const char *pathname, + uint32_t mask + ); } 255 AUE_NULL STD { - int linux_inotify_rm_watch(void); + int linux_inotify_rm_watch( + l_int fd, + uint32_t wd + ); } 256 AUE_NULL STD { int linux_migrate_pages(void); diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master index 7d796df1aed3..464d987ed0f4 100644 --- a/sys/amd64/linux32/syscalls.master +++ b/sys/amd64/linux32/syscalls.master @@ -1590,10 +1590,17 @@ int linux_inotify_init(void); } 292 AUE_NULL STD { - int linux_inotify_add_watch(void); + int linux_inotify_add_watch( + l_int fd, + const char *pathname, + uint32_t mask + ); } 293 AUE_NULL STD { - int linux_inotify_rm_watch(void); + int linux_inotify_rm_watch( + l_int fd, + uint32_t wd + ); } ; Linux 2.6.16: 294 AUE_NULL STD { @@ -1861,7 +1868,9 @@ ); } 332 AUE_NULL STD { - int linux_inotify_init1(void); + int linux_inotify_init1( + l_int flags + ); } ; Linux 2.6.30: 333 AUE_NULL STD { diff --git a/sys/arm64/linux/syscalls.master b/sys/arm64/linux/syscalls.master index 61c7499d57b3..615deca20f98 100644 --- a/sys/arm64/linux/syscalls.master +++ b/sys/arm64/linux/syscalls.master @@ -170,10 +170,17 @@ ); } 27 AUE_NULL STD { - int linux_inotify_add_watch(void); + int linux_inotify_add_watch( + l_int fd, + const char *pathname, + uint32_t mask + ); } 28 AUE_NULL STD { - int linux_inotify_rm_watch(void); + int linux_inotify_rm_watch( + l_int fd, + uint32_t wd + ); } 29 AUE_IOCTL STD { int linux_ioctl( diff --git a/sys/compat/linux/linux_dummy.c b/sys/compat/linux/linux_dummy.c index 35d6debe0da9..19cd55849f65 100644 --- a/sys/compat/linux/linux_dummy.c +++ b/sys/compat/linux/linux_dummy.c @@ -74,9 +74,6 @@ DUMMY(kexec_load); DUMMY(add_key); DUMMY(request_key); DUMMY(keyctl); -/* Linux 2.6.13: */ -DUMMY(inotify_add_watch); -DUMMY(inotify_rm_watch); /* Linux 2.6.16: */ DUMMY(migrate_pages); DUMMY(unshare); @@ -87,7 +84,6 @@ DUMMY(vmsplice); DUMMY(move_pages); /* Linux 2.6.27: */ DUMMY(signalfd4); -DUMMY(inotify_init1); /* Linux 2.6.31: */ DUMMY(perf_event_open); /* Linux 2.6.36: */ diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 4861dafe27b3..287549a11b30 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -32,11 +32,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -1877,3 +1879,122 @@ linux_writev(struct thread *td, struct linux_writev_args *args) freeuio(auio); return (linux_enobufs2eagain(td, args->fd, error)); } + +static int +linux_inotify_init_flags(int l_flags) +{ + int bsd_flags; + + if ((l_flags & ~(LINUX_IN_CLOEXEC | LINUX_IN_NONBLOCK)) != 0) + linux_msg(NULL, "inotify_init1 unsupported flags 0x%x", + l_flags); + + bsd_flags = 0; + if ((l_flags & LINUX_IN_CLOEXEC) != 0) + bsd_flags |= O_CLOEXEC; + if ((l_flags & LINUX_IN_NONBLOCK) != 0) + bsd_flags |= O_NONBLOCK; + return (bsd_flags); +} + +static int +inotify_init_common(struct thread *td, int flags) +{ + struct specialfd_inotify si; + + si.flags = linux_inotify_init_flags(flags); + return (kern_specialfd(td, SPECIALFD_INOTIFY, &si)); +} + +#if defined(__i386__) || defined(__amd64__) +int +linux_inotify_init(struct thread *td, struct linux_inotify_init_args *args) +{ + return (inotify_init_common(td, 0)); +} +#endif + +int +linux_inotify_init1(struct thread *td, struct linux_inotify_init1_args *args) +{ + return (inotify_init_common(td, args->flags)); +} + +/* + * The native implementation uses the same values for inotify events as + * libinotify, which gives us binary compatibility with Linux. This simplifies + * the shim implementation a lot, as otherwise we would have to handle read(2) + * calls on inotify descriptors and translate events to Linux's ABI. + */ +_Static_assert(LINUX_IN_ACCESS == IN_ACCESS, + "IN_ACCESS mismatch"); +_Static_assert(LINUX_IN_MODIFY == IN_MODIFY, + "IN_MODIFY mismatch"); +_Static_assert(LINUX_IN_ATTRIB == IN_ATTRIB, + "IN_ATTRIB mismatch"); +_Static_assert(LINUX_IN_CLOSE_WRITE == IN_CLOSE_WRITE, + "IN_CLOSE_WRITE mismatch"); +_Static_assert(LINUX_IN_CLOSE_NOWRITE == IN_CLOSE_NOWRITE, + "IN_CLOSE_NOWRITE mismatch"); +_Static_assert(LINUX_IN_OPEN == IN_OPEN, + "IN_OPEN mismatch"); +_Static_assert(LINUX_IN_MOVED_FROM == IN_MOVED_FROM, + "IN_MOVED_FROM mismatch"); +_Static_assert(LINUX_IN_MOVED_TO == IN_MOVED_TO, + "IN_MOVED_TO mismatch"); +_Static_assert(LINUX_IN_CREATE == IN_CREATE, + "IN_CREATE mismatch"); +_Static_assert(LINUX_IN_DELETE == IN_DELETE, + "IN_DELETE mismatch"); +_Static_assert(LINUX_IN_DELETE_SELF == IN_DELETE_SELF, + "IN_DELETE_SELF mismatch"); +_Static_assert(LINUX_IN_MOVE_SELF == IN_MOVE_SELF, + "IN_MOVE_SELF mismatch"); + +_Static_assert(LINUX_IN_UNMOUNT == IN_UNMOUNT, + "IN_UNMOUNT mismatch"); +_Static_assert(LINUX_IN_Q_OVERFLOW == IN_Q_OVERFLOW, + "IN_Q_OVERFLOW mismatch"); +_Static_assert(LINUX_IN_IGNORED == IN_IGNORED, + "IN_IGNORED mismatch"); + +_Static_assert(LINUX_IN_ISDIR == IN_ISDIR, + "IN_ISDIR mismatch"); +_Static_assert(LINUX_IN_ONLYDIR == IN_ONLYDIR, + "IN_ONLYDIR mismatch"); +_Static_assert(LINUX_IN_DONT_FOLLOW == IN_DONT_FOLLOW, + "IN_DONT_FOLLOW mismatch"); +_Static_assert(LINUX_IN_MASK_CREATE == IN_MASK_CREATE, + "IN_MASK_CREATE mismatch"); +_Static_assert(LINUX_IN_MASK_ADD == IN_MASK_ADD, + "IN_MASK_ADD mismatch"); +_Static_assert(LINUX_IN_ONESHOT == IN_ONESHOT, + "IN_ONESHOT mismatch"); +_Static_assert(LINUX_IN_EXCL_UNLINK == IN_EXCL_UNLINK, + "IN_EXCL_UNLINK mismatch"); + +static int +linux_inotify_watch_flags(int l_flags) +{ + if ((l_flags & ~(LINUX_IN_ALL_EVENTS | LINUX_IN_ALL_FLAGS)) != 0) { + linux_msg(NULL, "inotify_add_watch unsupported flags 0x%x", + l_flags); + } + + return (l_flags); +} + +int +linux_inotify_add_watch(struct thread *td, + struct linux_inotify_add_watch_args *args) +{ + return (kern_inotify_add_watch(args->fd, AT_FDCWD, args->pathname, + linux_inotify_watch_flags(args->mask), td)); +} + +int +linux_inotify_rm_watch(struct thread *td, + struct linux_inotify_rm_watch_args *args) +{ + return (kern_inotify_rm_watch(args->fd, args->wd, td)); +} diff --git a/sys/compat/linux/linux_file.h b/sys/compat/linux/linux_file.h index ce9feca154ed..332a7b33c697 100644 --- a/sys/compat/linux/linux_file.h +++ b/sys/compat/linux/linux_file.h @@ -189,6 +189,38 @@ #define LINUX_HUGETLB_FLAG_ENCODE_2GB (31 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_16GB (34U << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) +/* inotify flags */ +#define LINUX_IN_ACCESS 0x00000001 +#define LINUX_IN_MODIFY 0x00000002 +#define LINUX_IN_ATTRIB 0x00000004 +#define LINUX_IN_CLOSE_WRITE 0x00000008 +#define LINUX_IN_CLOSE_NOWRITE 0x00000010 +#define LINUX_IN_OPEN 0x00000020 +#define LINUX_IN_MOVED_FROM 0x00000040 +#define LINUX_IN_MOVED_TO 0x00000080 +#define LINUX_IN_CREATE 0x00000100 +#define LINUX_IN_DELETE 0x00000200 +#define LINUX_IN_DELETE_SELF 0x00000400 +#define LINUX_IN_MOVE_SELF 0x00000800 + +#define LINUX_IN_UNMOUNT 0x00002000 +#define LINUX_IN_Q_OVERFLOW 0x00004000 +#define LINUX_IN_IGNORED 0x00008000 + +#define LINUX_IN_ONLYDIR 0x01000000 +#define LINUX_IN_DONT_FOLLOW 0x02000000 +#define LINUX_IN_EXCL_UNLINK 0x04000000 +#define LINUX_IN_MASK_CREATE 0x10000000 +#define LINUX_IN_MASK_ADD 0x20000000 +#define LINUX_IN_ISDIR 0x40000000 +#define LINUX_IN_ONESHOT 0x80000000 + +#define LINUX_IN_ALL_EVENTS 0x00000fff +#define LINUX_IN_ALL_FLAGS 0xf700e000 + +#define LINUX_IN_NONBLOCK 0x00000800 +#define LINUX_IN_CLOEXEC 0x00080000 + #if defined(_KERNEL) struct l_file_handle { l_uint handle_bytes; diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master index e3c39e50986c..450479432ed6 100644 --- a/sys/i386/linux/syscalls.master +++ b/sys/i386/linux/syscalls.master @@ -1606,10 +1606,17 @@ int linux_inotify_init(void); } 292 AUE_NULL STD { - int linux_inotify_add_watch(void); + int linux_inotify_add_watch( + l_int fd, + const char *pathname, + uint32_t mask + ); } 293 AUE_NULL STD { - int linux_inotify_rm_watch(void); + int linux_inotify_rm_watch( + l_int fd, + uint32_t wd + ); } ; Linux 2.6.16: 294 AUE_NULL STD { @@ -1873,7 +1880,9 @@ ); } 332 AUE_NULL STD { - int linux_inotify_init1(void); + int linux_inotify_init1( + l_int flags + ); } ; Linux 2.6.30: 333 AUE_NULL STD { diff --git a/sys/kern/vfs_inotify.c b/sys/kern/vfs_inotify.c index 91d3e8d5f0fd..3542989c6a48 100644 --- a/sys/kern/vfs_inotify.c +++ b/sys/kern/vfs_inotify.c @@ -869,7 +869,7 @@ fget_inotify(struct thread *td, int fd, const cap_rights_t *needrightsp, return (0); } -static int +int kern_inotify_add_watch(int fd, int dfd, const char *path, uint32_t mask, struct thread *td) { @@ -954,7 +954,7 @@ sys_inotify_add_watch_at(struct thread *td, uap->mask, td)); } -static int +int kern_inotify_rm_watch(int fd, uint32_t wd, struct thread *td) { struct file *fp; diff --git a/sys/sys/inotify.h b/sys/sys/inotify.h index 6a266aacce32..65dc5dba43f3 100644 --- a/sys/sys/inotify.h +++ b/sys/sys/inotify.h @@ -89,6 +89,10 @@ struct vnode; int inotify_create_file(struct thread *, struct file *, int, int *); void inotify_log(struct vnode *, const char *, size_t, int, __uint32_t); +int kern_inotify_rm_watch(int, uint32_t, struct thread *); +int kern_inotify_add_watch(int, int, const char *, uint32_t, + struct thread *); + void vn_inotify(struct vnode *, struct vnode *, struct componentname *, int, uint32_t); int vn_inotify_add_watch(struct vnode *, struct inotify_softc *, diff --git a/sys/x86/linux/linux_dummy_x86.c b/sys/x86/linux/linux_dummy_x86.c index ae1d23e811e7..221f5dbf5ba3 100644 --- a/sys/x86/linux/linux_dummy_x86.c +++ b/sys/x86/linux/linux_dummy_x86.c @@ -46,7 +46,5 @@ LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); DUMMY(sysfs); DUMMY(quotactl); -/* Linux 2.6.13: */ -DUMMY(inotify_init); /* Linux 2.6.22: */ DUMMY(signalfd);