aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_inotify.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/vfs_inotify.c')
-rw-r--r--sys/kern/vfs_inotify.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/kern/vfs_inotify.c b/sys/kern/vfs_inotify.c
index b265a5ff3a62..fd1ef39b13f7 100644
--- a/sys/kern/vfs_inotify.c
+++ b/sys/kern/vfs_inotify.c
@@ -111,6 +111,7 @@ static const struct filterops inotify_rfiltops = {
.f_isfd = 1,
.f_detach = filt_inotifydetach,
.f_event = filt_inotifyevent,
+ .f_copy = knote_triv_copy,
};
static MALLOC_DEFINE(M_INOTIFY, "inotify", "inotify data structures");
@@ -380,7 +381,14 @@ inotify_unlink_watch_locked(struct inotify_softc *sc, struct inotify_watch *watc
static void
inotify_free_watch(struct inotify_watch *watch)
{
- vrele(watch->vp);
+ /*
+ * Formally, we don't need to lock the vnode here. However, if we
+ * don't, and vrele() releases the last reference, it's possible the
+ * vnode will be recycled while a different thread holds the vnode lock.
+ * Work around this bug by acquiring the lock here.
+ */
+ (void)vn_lock(watch->vp, LK_EXCLUSIVE | LK_RETRY);
+ vput(watch->vp);
free(watch, M_INOTIFY);
}