diff --git a/sys/kern/vfs_inotify.c b/sys/kern/vfs_inotify.c index 94e65973a36b..862442714690 100644 --- a/sys/kern/vfs_inotify.c +++ b/sys/kern/vfs_inotify.c @@ -614,26 +614,34 @@ inotify_log_one(struct inotify_watch *watch, const char *name, size_t namelen, struct inotify_watch key; struct inotify_softc *sc; struct inotify_record *rec; - bool allocfail; + bool allocfail = false; + bool enabled = (watch->mask & event) != 0; + bool delete = (event & (IN_DELETE_SELF | IN_UNMOUNT)) != 0; + + if (!enabled && !delete) + return; mtx_assert(&watch->vp->v_pollinfo->vpi_lock, MA_OWNED); sc = watch->sc; - rec = inotify_alloc_record(watch->wd, name, namelen, event, cookie, - M_NOWAIT); - if (rec == NULL) { - rec = &sc->overflow; - allocfail = true; - } else { - allocfail = false; + mtx_lock(&sc->lock); + + if (enabled) { + rec = inotify_alloc_record(watch->wd, name, namelen, event, cookie, + M_NOWAIT); + if (rec == NULL) { + rec = &sc->overflow; + allocfail = true; + } + + if (!inotify_queue_record(sc, rec) && rec != &sc->overflow) + free(rec, M_INOTIFY); + if ((watch->mask & IN_ONESHOT) != 0) + delete = true; } - mtx_lock(&sc->lock); - if (!inotify_queue_record(sc, rec) && rec != &sc->overflow) - free(rec, M_INOTIFY); - if ((watch->mask & IN_ONESHOT) != 0 || - (event & (IN_DELETE_SELF | IN_UNMOUNT)) != 0) { - if (!allocfail) { + if (delete) { + if (!allocfail && (watch->mask & IN_IGNORED) != 0) { rec = inotify_alloc_record(watch->wd, NULL, 0, IN_IGNORED, 0, M_NOWAIT); if (rec == NULL) @@ -676,8 +684,7 @@ inotify_log(struct vnode *vp, const char *name, size_t namelen, int event, TAILQ_FOREACH_SAFE(watch, &vp->v_pollinfo->vpi_inotify, vlink, tmp) { KASSERT(watch->vp == vp, ("inotify_log: watch %p vp != vp", watch)); - if ((watch->mask & event) != 0 || event == IN_UNMOUNT) - inotify_log_one(watch, name, namelen, event, cookie); + inotify_log_one(watch, name, namelen, event, cookie); } mtx_unlock(&vp->v_pollinfo->vpi_lock); }