The branch main has been updated by markj:

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

commit af0ec3fa29cad823d0196538381f1e832f5974a7
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2025-07-18 14:25:28 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2025-07-18 14:25:28 +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
---
 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 2b42228465a4..d3cd0d1f9832 100644
--- a/sys/kern/vfs_inotify.c
+++ b/sys/kern/vfs_inotify.c
@@ -371,7 +371,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);
 }
 
 /*
@@ -675,7 +675,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 {                                         
\

Reply via email to