git: 9f2c32c1924b - stable/14 - inotify: Fix a couple of locking bugs

Mark Johnston <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a7353db.4602b.33587ee2__21140.833564435$1785943230$gmane$org@gitrepo.freebsd.org>
The branch stable/14 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=9f2c32c1924b524f9e353bee74884d263b273a4f

commit 9f2c32c1924b524f9e353bee74884d263b273a4f
Author:     Mark Johnston <[email protected]>
AuthorDate: 2025-07-18 14:25:28 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2026-08-05 15:15:16 +0000

    inotify: Fix a couple of locking bugs
    
    When hooking vop_rename_post(), the preexisting dst vnode will be
    unlocked.  But, we need to invoke VOP_GETATTR on it in vn_inotify() to
    check its link count.
    
    In inotify_unlink_watch_locked(), the vnode interlock is not held, so
    don't use vn_irflag_unset_locked().
    
    Reviewed by:    kib
    Fixes:          f1f230439fa4 ("vfs: Initial revision of inotify")
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D51401
    
    (cherry picked from commit af0ec3fa29cad823d0196538381f1e832f5974a7)
---
 sys/kern/vfs_inotify.c |  5 +++--
 sys/sys/inotify.h      | 14 +++++++++++---
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/sys/kern/vfs_inotify.c b/sys/kern/vfs_inotify.c
index 46971c78440c..035c2c9eb290 100644
--- a/sys/kern/vfs_inotify.c
+++ b/sys/kern/vfs_inotify.c
@@ -368,7 +368,7 @@ inotify_unlink_watch_locked(struct inotify_softc *sc, struct inotify_watch *watc
 
 	TAILQ_REMOVE(&vp->v_pollinfo->vpi_inotify, watch, vlink);
 	if (TAILQ_EMPTY(&vp->v_pollinfo->vpi_inotify))
-		vn_irflag_unset_locked(vp, VIRF_INOTIFY);
+		vn_irflag_unset(vp, VIRF_INOTIFY);
 }
 
 /*
@@ -672,7 +672,8 @@ vn_inotify(struct vnode *vp, struct vnode *dvp, struct componentname *cnp,
 					struct vattr va;
 					int error;
 
-					error = VOP_GETATTR(vp, &va, cnp->cn_cred);
+					error = VOP_GETATTR(vp, &va,
+					    cnp->cn_cred);
 					if (error == 0 && va.va_nlink != 0)
 						selfevent = 0;
 				}
diff --git a/sys/sys/inotify.h b/sys/sys/inotify.h
index 65dc5dba43f3..d1f23d5898bb 100644
--- a/sys/sys/inotify.h
+++ b/sys/sys/inotify.h
@@ -107,11 +107,18 @@ void	vn_inotify_revoke(struct vnode *);
 } while (0)
 
 /* Log an inotify event using a specific name for the vnode. */
-#define	INOTIFY_NAME(vp, dvp, cnp, ev) do {				\
+#define	INOTIFY_NAME_LOCK(vp, dvp, cnp, ev, lock) do {			\
 	if (__predict_false((vn_irflag_read(vp) & VIRF_INOTIFY) != 0 ||	\
-	    (vn_irflag_read(dvp) & VIRF_INOTIFY) != 0)) 		\
+	    (vn_irflag_read(dvp) & VIRF_INOTIFY) != 0)) {		\
+		if (lock)						\
+			vn_lock((vp), LK_SHARED | LK_RETRY);		\
 		VOP_INOTIFY((vp), (dvp), (cnp), (ev), 0);		\
+		if (lock)						\
+			VOP_UNLOCK(vp);					\
+	}								\
 } while (0)
+#define	INOTIFY_NAME(vp, dvp, cnp, ev)					\
+	INOTIFY_NAME_LOCK((vp), (dvp), (cnp), (ev), false)
 
 extern __uint32_t inotify_rename_cookie;
 
@@ -126,7 +133,8 @@ extern __uint32_t inotify_rename_cookie;
 		VOP_INOTIFY((vp), (tdvp), (tcnp), IN_MOVED_TO, cookie);	\
 	}								\
 	if ((tvp) != NULL)						\
-		INOTIFY_NAME((tvp), (tdvp), (tcnp), _IN_MOVE_DELETE);	\
+		INOTIFY_NAME_LOCK((tvp), (tdvp), (tcnp),		\
+		    _IN_MOVE_DELETE, true);				\
 } while (0)
 
 #define	INOTIFY_REVOKE(vp) do {						\
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.