Module Name:    src
Committed By:   snj
Date:           Sat Jul  8 16:52:27 UTC 2017

Modified Files:
        src/sys/kern [netbsd-7-1]: kern_event.c
        src/sys/miscfs/genfs [netbsd-7-1]: genfs_vnops.c
        src/sys/sys [netbsd-7-1]: event.h

Log Message:
Pull up following revision(s) (requested by christos in ticket #1442):
        sys/kern/kern_event.c: revision 1.92 via patch
        sys/miscfs/genfs/genfs_vnops.c: revision 1.198 via patch
        sys/sys/event.h: revision 1.30 via patch
Provide EVFILT_WRITE; this is what FreeBSD does and go wants it.
Makes go unit tests pass.
--
fix file descriptor locking (from joerg).
fixes kernel crashes by running go


To generate a diff of this commit:
cvs rdiff -u -r1.80.2.1 -r1.80.2.1.6.1 src/sys/kern/kern_event.c
cvs rdiff -u -r1.192 -r1.192.14.1 src/sys/miscfs/genfs/genfs_vnops.c
cvs rdiff -u -r1.23 -r1.23.36.1 src/sys/sys/event.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_event.c
diff -u src/sys/kern/kern_event.c:1.80.2.1 src/sys/kern/kern_event.c:1.80.2.1.6.1
--- src/sys/kern/kern_event.c:1.80.2.1	Tue Apr 14 04:39:58 2015
+++ src/sys/kern/kern_event.c	Sat Jul  8 16:52:27 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_event.c,v 1.80.2.1 2015/04/14 04:39:58 snj Exp $	*/
+/*	$NetBSD: kern_event.c,v 1.80.2.1.6.1 2017/07/08 16:52:27 snj Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -58,11 +58,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.80.2.1 2015/04/14 04:39:58 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.80.2.1.6.1 2017/07/08 16:52:27 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/wait.h>
 #include <sys/proc.h>
 #include <sys/file.h>
 #include <sys/select.h>
@@ -779,7 +780,7 @@ sys_kqueue1(struct lwp *l, const struct 
  * kevent(2) system call.
  */
 int
-kevent_fetch_changes(void *private, const struct kevent *changelist,
+kevent_fetch_changes(void *ctx, const struct kevent *changelist,
     struct kevent *changes, size_t index, int n)
 {
 
@@ -787,7 +788,7 @@ kevent_fetch_changes(void *private, cons
 }
 
 int
-kevent_put_events(void *private, struct kevent *events,
+kevent_put_events(void *ctx, struct kevent *events,
     struct kevent *eventlist, size_t index, int n)
 {
 
@@ -851,7 +852,7 @@ kevent1(register_t *retval, int fd,
 		timeout = &ts;
 	}
 
-	kq = (struct kqueue *)fp->f_data;
+	kq = fp->f_data;
 	nerrors = 0;
 	ichange = 0;
 
@@ -867,21 +868,19 @@ kevent1(register_t *retval, int fd,
 			kevp->flags &= ~EV_SYSFLAGS;
 			/* register each knote */
 			error = kqueue_register(kq, kevp);
-			if (error) {
-				if (nevents != 0) {
-					kevp->flags = EV_ERROR;
-					kevp->data = error;
-					error = (*keops->keo_put_events)
-					    (keops->keo_private, kevp,
-					    eventlist, nerrors, 1);
-					if (error)
-						goto done;
-					nevents--;
-					nerrors++;
-				} else {
-					goto done;
-				}
-			}
+			if (!error && !(kevp->flags & EV_RECEIPT))
+				continue;
+			if (nevents == 0)
+				goto done;
+			kevp->flags = EV_ERROR;
+			kevp->data = error;
+			error = (*keops->keo_put_events)
+				(keops->keo_private, kevp,
+				 eventlist, nerrors, 1);
+			if (error)
+				goto done;
+			nevents--;
+			nerrors++;
 		}
 		nchanges -= n;	/* update the results */
 		ichange += n;
@@ -934,8 +933,9 @@ kqueue_register(struct kqueue *kq, struc
 	/* search if knote already exists */
 	if (kfilter->filtops->f_isfd) {
 		/* monitoring a file descriptor */
-		fd = kev->ident;
-		if ((fp = fd_getfile(fd)) == NULL) {
+		/* validate descriptor */
+		if (kev->ident > INT_MAX
+		    || (fp = fd_getfile(fd = kev->ident)) == NULL) {
 			rw_exit(&kqueue_filter_lock);
 			kmem_free(newkn, sizeof(*newkn));
 			return EBADF;
@@ -986,6 +986,7 @@ kqueue_register(struct kqueue *kq, struc
 			kev->data = 0;
 			kn->kn_kevent = *kev;
 
+			KASSERT(kn->kn_fop != NULL);
 			/*
 			 * apply reference count to knote structure, and
 			 * do not release it at the end of this routine.
@@ -1019,8 +1020,11 @@ kqueue_register(struct kqueue *kq, struc
 			KERNEL_UNLOCK_ONE(NULL);	/* XXXSMP */
 			if (error != 0) {
 #ifdef DIAGNOSTIC
-				printf("%s: event not supported for file type"
-				    " %d\n", __func__, fp ? fp->f_type : -1);
+				
+				printf("%s: event type %d not supported for "
+				    "file type %d (error %d)\n", __func__,
+				    kn->kn_filter, kn->kn_obj ?
+				    ((file_t *)kn->kn_obj)->f_type : -1, error);
 #endif
 				/* knote_detach() drops fdp->fd_lock */
 				knote_detach(kn, fdp, false);
@@ -1043,6 +1047,7 @@ kqueue_register(struct kqueue *kq, struc
 		 * support events, and the attach routine is
 		 * broken and does not return an error.
 		 */
+		KASSERT(kn->kn_fop != NULL);
 		KASSERT(kn->kn_fop->f_event != NULL);
 		KERNEL_LOCK(1, NULL);			/* XXXSMP */
 		rv = (*kn->kn_fop->f_event)(kn, 0);
@@ -1150,7 +1155,7 @@ kqueue_scan(file_t *fp, size_t maxevents
 	struct kqueue	*kq;
 	struct kevent	*kevp;
 	struct timespec	ats, sleepts;
-	struct knote	*kn, *marker;
+	struct knote	*kn, *marker, morker;
 	size_t		count, nkev, nevents;
 	int		timeout, error, rv;
 	filedesc_t	*fdp;
@@ -1178,7 +1183,8 @@ kqueue_scan(file_t *fp, size_t maxevents
 		timeout = 0;
 	}	
 
-	marker = kmem_zalloc(sizeof(*marker), KM_SLEEP);
+	memset(&morker, 0, sizeof(morker));
+	marker = &morker;
 	marker->kn_status = KN_MARKER;
 	mutex_spin_enter(&kq->kq_lock);
  retry:
@@ -1199,10 +1205,19 @@ kqueue_scan(file_t *fp, size_t maxevents
 					error = 0;
 			}
 		}
+		mutex_spin_exit(&kq->kq_lock);
 	} else {
 		/* mark end of knote list */
 		TAILQ_INSERT_TAIL(&kq->kq_head, marker, kn_tqe);
 
+		/*
+		 * Acquire the fdp->fd_lock interlock to avoid races with
+		 * file creation/destruction from other threads.
+		 */
+		mutex_spin_exit(&kq->kq_lock);
+		mutex_enter(&fdp->fd_lock);
+		mutex_spin_enter(&kq->kq_lock);
+
 		while (count != 0) {
 			kn = TAILQ_FIRST(&kq->kq_head);	/* get next knote */
 			while ((kn->kn_status & KN_MARKER) != 0) {
@@ -1213,35 +1228,43 @@ kqueue_scan(file_t *fp, size_t maxevents
 					    (timeout = gettimeleft(&ats,
 					    &sleepts)) <= 0))
 						goto done;
+					mutex_exit(&fdp->fd_lock);
 					goto retry;
 				}
 				/* someone else's marker. */
 				kn = TAILQ_NEXT(kn, kn_tqe);
 			}
 			kq_check(kq);
-			TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
 			kq->kq_count--;
+			TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
 			kn->kn_status &= ~KN_QUEUED;
+			kn->kn_status |= KN_BUSY;
 			kq_check(kq);
 			if (kn->kn_status & KN_DISABLED) {
+				kn->kn_status &= ~KN_BUSY;
 				/* don't want disabled events */
 				continue;
 			}
 			if ((kn->kn_flags & EV_ONESHOT) == 0) {
 				mutex_spin_exit(&kq->kq_lock);
+				KASSERT(kn->kn_fop != NULL);
+				KASSERT(kn->kn_fop->f_event != NULL);
 				KERNEL_LOCK(1, NULL);		/* XXXSMP */
+				KASSERT(mutex_owned(&fdp->fd_lock));
 				rv = (*kn->kn_fop->f_event)(kn, 0);
 				KERNEL_UNLOCK_ONE(NULL);	/* XXXSMP */
 				mutex_spin_enter(&kq->kq_lock);
 				/* Re-poll if note was re-enqueued. */
-				if ((kn->kn_status & KN_QUEUED) != 0)
+				if ((kn->kn_status & KN_QUEUED) != 0) {
+					kn->kn_status &= ~KN_BUSY;
 					continue;
+				}
 				if (rv == 0) {
 					/*
 					 * non-ONESHOT event that hasn't
 					 * triggered again, so de-queue.
 					 */
-					kn->kn_status &= ~KN_ACTIVE;
+					kn->kn_status &= ~(KN_ACTIVE|KN_BUSY);
 					continue;
 				}
 			}
@@ -1250,29 +1273,36 @@ kqueue_scan(file_t *fp, size_t maxevents
 			nkev++;
 			if (kn->kn_flags & EV_ONESHOT) {
 				/* delete ONESHOT events after retrieval */
+				kn->kn_status &= ~KN_BUSY;
 				mutex_spin_exit(&kq->kq_lock);
-				mutex_enter(&fdp->fd_lock);
 				knote_detach(kn, fdp, true);
+				mutex_enter(&fdp->fd_lock);
 				mutex_spin_enter(&kq->kq_lock);
 			} else if (kn->kn_flags & EV_CLEAR) {
 				/* clear state after retrieval */
 				kn->kn_data = 0;
 				kn->kn_fflags = 0;
-				kn->kn_status &= ~KN_ACTIVE;
+				kn->kn_status &= ~(KN_QUEUED|KN_ACTIVE|KN_BUSY);
+			} else if (kn->kn_flags & EV_DISPATCH) {
+				kn->kn_status |= KN_DISABLED;
+				kn->kn_status &= ~(KN_QUEUED|KN_ACTIVE|KN_BUSY);
 			} else {
 				/* add event back on list */
 				kq_check(kq);
+				kn->kn_status |= KN_QUEUED;
+				kn->kn_status &= ~KN_BUSY;
 				TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
 				kq->kq_count++;
-				kn->kn_status |= KN_QUEUED;
 				kq_check(kq);
 			}
 			if (nkev == kevcnt) {
 				/* do copyouts in kevcnt chunks */
 				mutex_spin_exit(&kq->kq_lock);
+				mutex_exit(&fdp->fd_lock);
 				error = (*keops->keo_put_events)
 				    (keops->keo_private,
 				    kevbuf, ulistp, nevents, nkev);
+				mutex_enter(&fdp->fd_lock);
 				mutex_spin_enter(&kq->kq_lock);
 				nevents += nkev;
 				nkev = 0;
@@ -1285,11 +1315,10 @@ kqueue_scan(file_t *fp, size_t maxevents
 				break;
 			}
 		}
-	}
  done:
- 	mutex_spin_exit(&kq->kq_lock);
-	if (marker != NULL)
-		kmem_free(marker, sizeof(*marker));
+		mutex_spin_exit(&kq->kq_lock);
+		mutex_exit(&fdp->fd_lock);
+	}
 	if (nkev != 0) {
 		/* copyout remaining events */
 		error = (*keops->keo_put_events)(keops->keo_private,
@@ -1510,6 +1539,8 @@ knote(struct klist *list, long hint)
 	struct knote *kn, *tmpkn;
 
 	SLIST_FOREACH_SAFE(kn, list, kn_selnext, tmpkn) {
+		KASSERT(kn->kn_fop != NULL);
+		KASSERT(kn->kn_fop->f_event != NULL);
 		if ((*kn->kn_fop->f_event)(kn, hint))
 			knote_activate(kn);
 	}
@@ -1550,8 +1581,10 @@ knote_detach(struct knote *kn, filedesc_
 	KASSERT((kn->kn_status & KN_MARKER) == 0);
 	KASSERT(mutex_owned(&fdp->fd_lock));
 
+	KASSERT(kn->kn_fop != NULL);
 	/* Remove from monitored object. */
 	if (dofop) {
+		KASSERT(kn->kn_fop->f_detach != NULL);
 		KERNEL_LOCK(1, NULL);		/* XXXSMP */
 		(*kn->kn_fop->f_detach)(kn);
 		KERNEL_UNLOCK_ONE(NULL);	/* XXXSMP */
@@ -1566,14 +1599,17 @@ knote_detach(struct knote *kn, filedesc_
 	SLIST_REMOVE(list, kn, knote, kn_link);
 
 	/* Remove from kqueue. */
-	/* XXXAD should verify not in use by kqueue_scan. */
+again:
 	mutex_spin_enter(&kq->kq_lock);
 	if ((kn->kn_status & KN_QUEUED) != 0) {
 		kq_check(kq);
+		kq->kq_count--;
 		TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
 		kn->kn_status &= ~KN_QUEUED;
-		kq->kq_count--;
 		kq_check(kq);
+	} else if (kn->kn_status & KN_BUSY) {
+		mutex_spin_exit(&kq->kq_lock);
+		goto again;
 	}
 	mutex_spin_exit(&kq->kq_lock);
 
@@ -1602,8 +1638,8 @@ knote_enqueue(struct knote *kn)
 	}
 	if ((kn->kn_status & (KN_ACTIVE | KN_QUEUED)) == KN_ACTIVE) {
 		kq_check(kq);
-		TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
 		kn->kn_status |= KN_QUEUED;
+		TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
 		kq->kq_count++;
 		kq_check(kq);
 		cv_broadcast(&kq->kq_cv);
@@ -1627,8 +1663,8 @@ knote_activate(struct knote *kn)
 	kn->kn_status |= KN_ACTIVE;
 	if ((kn->kn_status & (KN_QUEUED | KN_DISABLED)) == 0) {
 		kq_check(kq);
-		TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
 		kn->kn_status |= KN_QUEUED;
+		TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
 		kq->kq_count++;
 		kq_check(kq);
 		cv_broadcast(&kq->kq_cv);

Index: src/sys/miscfs/genfs/genfs_vnops.c
diff -u src/sys/miscfs/genfs/genfs_vnops.c:1.192 src/sys/miscfs/genfs/genfs_vnops.c:1.192.14.1
--- src/sys/miscfs/genfs/genfs_vnops.c:1.192	Mon Mar 24 13:42:40 2014
+++ src/sys/miscfs/genfs/genfs_vnops.c	Sat Jul  8 16:52:27 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: genfs_vnops.c,v 1.192 2014/03/24 13:42:40 hannken Exp $	*/
+/*	$NetBSD: genfs_vnops.c,v 1.192.14.1 2017/07/08 16:52:27 snj Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.192 2014/03/24 13:42:40 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.192.14.1 2017/07/08 16:52:27 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -548,6 +548,32 @@ filt_genfsread(struct knote *kn, long hi
 }
 
 static int
+filt_genfswrite(struct knote *kn, long hint)
+{
+	struct vnode *vp = (struct vnode *)kn->kn_hook;
+
+	/*
+	 * filesystem is gone, so set the EOF flag and schedule
+	 * the knote for deletion.
+	 */
+	switch (hint) {
+	case NOTE_REVOKE:
+		KASSERT(mutex_owned(vp->v_interlock));
+		kn->kn_flags |= (EV_EOF | EV_ONESHOT);
+		return (1);
+	case 0:
+		mutex_enter(vp->v_interlock);
+		kn->kn_data = 0;
+		mutex_exit(vp->v_interlock);
+		return 1;
+	default:
+		KASSERT(mutex_owned(vp->v_interlock));
+		kn->kn_data = 0;
+		return 1;
+	}
+}
+
+static int
 filt_genfsvnode(struct knote *kn, long hint)
 {
 	struct vnode *vp = (struct vnode *)kn->kn_hook;
@@ -578,6 +604,8 @@ filt_genfsvnode(struct knote *kn, long h
 
 static const struct filterops genfsread_filtops =
 	{ 1, NULL, filt_genfsdetach, filt_genfsread };
+static const struct filterops genfswrite_filtops =
+	{ 1, NULL, filt_genfsdetach, filt_genfswrite };
 static const struct filterops genfsvnode_filtops =
 	{ 1, NULL, filt_genfsdetach, filt_genfsvnode };
 
@@ -597,6 +625,9 @@ genfs_kqfilter(void *v)
 	case EVFILT_READ:
 		kn->kn_fop = &genfsread_filtops;
 		break;
+	case EVFILT_WRITE:
+		kn->kn_fop = &genfswrite_filtops;
+		break;
 	case EVFILT_VNODE:
 		kn->kn_fop = &genfsvnode_filtops;
 		break;

Index: src/sys/sys/event.h
diff -u src/sys/sys/event.h:1.23 src/sys/sys/event.h:1.23.36.1
--- src/sys/sys/event.h:1.23	Sun Jun 26 16:43:12 2011
+++ src/sys/sys/event.h	Sat Jul  8 16:52:27 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: event.h,v 1.23 2011/06/26 16:43:12 christos Exp $	*/
+/*	$NetBSD: event.h,v 1.23.36.1 2017/07/08 16:52:27 snj Exp $	*/
 
 /*-
  * Copyright (c) 1999,2000,2001 Jonathan Lemon <[email protected]>
@@ -36,25 +36,14 @@
 #include <sys/inttypes.h>		/* for uintptr_t */
 #include <sys/null.h>			/* for NULL */
 
-#define	EVFILT_READ		0
-#define	EVFILT_WRITE		1
-#define	EVFILT_AIO		2	/* attached to aio requests */
-#define	EVFILT_VNODE		3	/* attached to vnodes */
-#define	EVFILT_PROC		4	/* attached to struct proc */
-#define	EVFILT_SIGNAL		5	/* attached to struct proc */
-#define	EVFILT_TIMER		6	/* arbitrary timer (in ms) */
-#define	EVFILT_SYSCOUNT		7	/* number of filters */
-
-#define	EV_SET(kevp, a, b, c, d, e, f)					\
-do {									\
-	(kevp)->ident = (a);						\
-	(kevp)->filter = (b);						\
-	(kevp)->flags = (c);						\
-	(kevp)->fflags = (d);						\
-	(kevp)->data = (e);						\
-	(kevp)->udata = (f);						\
-} while (/* CONSTCOND */ 0)
-
+#define	EVFILT_READ		0U
+#define	EVFILT_WRITE		1U
+#define	EVFILT_AIO		2U	/* attached to aio requests */
+#define	EVFILT_VNODE		3U	/* attached to vnodes */
+#define	EVFILT_PROC		4U	/* attached to struct proc */
+#define	EVFILT_SIGNAL		5U	/* attached to struct proc */
+#define	EVFILT_TIMER		6U	/* arbitrary timer (in ms) */
+#define	EVFILT_SYSCOUNT		7U	/* number of filters */
 
 struct kevent {
 	uintptr_t	ident;		/* identifier for this event */
@@ -65,58 +54,76 @@ struct kevent {
 	intptr_t	udata;		/* opaque user data identifier */
 };
 
+#define EV_SET(kevp, ident, filter, flags, fflags, data, udata)	\
+    _EV_SET((kevp), __CAST(uintptr_t, (ident)), (filter), (flags), \
+    (fflags), (data), __CAST(intptr_t, (udata)))
+
+static __inline void
+_EV_SET(struct kevent *_kevp, uintptr_t _ident, uint32_t _filter,
+    uint32_t _flags, uint32_t _fflags, int64_t _data, intptr_t _udata)
+{
+	_kevp->ident = _ident;
+	_kevp->filter = _filter;
+	_kevp->flags = _flags;
+	_kevp->fflags = _fflags;
+	_kevp->data = _data;
+	_kevp->udata = _udata;
+}
+
 /* actions */
-#define	EV_ADD		0x0001		/* add event to kq (implies ENABLE) */
-#define	EV_DELETE	0x0002		/* delete event from kq */
-#define	EV_ENABLE	0x0004		/* enable event */
-#define	EV_DISABLE	0x0008		/* disable event (not reported) */
+#define	EV_ADD		0x0001U		/* add event to kq (implies ENABLE) */
+#define	EV_DELETE	0x0002U		/* delete event from kq */
+#define	EV_ENABLE	0x0004U		/* enable event */
+#define	EV_DISABLE	0x0008U		/* disable event (not reported) */
 
 /* flags */
-#define	EV_ONESHOT	0x0010		/* only report one occurrence */
-#define	EV_CLEAR	0x0020		/* clear event state after reporting */
+#define	EV_ONESHOT	0x0010U		/* only report one occurrence */
+#define	EV_CLEAR	0x0020U		/* clear event state after reporting */
+#define EV_RECEIPT	0x0040U		/* force EV_ERROR on success, data=0 */
+#define EV_DISPATCH	0x0080U		/* disable event after reporting */
 
-#define	EV_SYSFLAGS	0xF000		/* reserved by system */
-#define	EV_FLAG1	0x2000		/* filter-specific flag */
+#define	EV_SYSFLAGS	0xF000U		/* reserved by system */
+#define	EV_FLAG1	0x2000U		/* filter-specific flag */
 
 /* returned values */
-#define	EV_EOF		0x8000		/* EOF detected */
-#define	EV_ERROR	0x4000		/* error, data contains errno */
+#define	EV_EOF		0x8000U		/* EOF detected */
+#define	EV_ERROR	0x4000U		/* error, data contains errno */
 
 /*
  * hint flag for in-kernel use - must not equal any existing note
  */
 #ifdef _KERNEL
-#define NOTE_SUBMIT	0x01000000		/* initial knote submission */
+#define NOTE_SUBMIT	0x01000000U		/* initial knote submission */
 #endif
 /*
  * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
  */
-#define	NOTE_LOWAT	0x0001			/* low water mark */
+#define	NOTE_LOWAT	0x0001U			/* low water mark */
 
 /*
  * data/hint flags for EVFILT_VNODE, shared with userspace
  */
-#define	NOTE_DELETE	0x0001			/* vnode was removed */
-#define	NOTE_WRITE	0x0002			/* data contents changed */
-#define	NOTE_EXTEND	0x0004			/* size increased */
-#define	NOTE_ATTRIB	0x0008			/* attributes changed */
-#define	NOTE_LINK	0x0010			/* link count changed */
-#define	NOTE_RENAME	0x0020			/* vnode was renamed */
-#define	NOTE_REVOKE	0x0040			/* vnode access was revoked */
+#define	NOTE_DELETE	0x0001U			/* vnode was removed */
+#define	NOTE_WRITE	0x0002U			/* data contents changed */
+#define	NOTE_EXTEND	0x0004U			/* size increased */
+#define	NOTE_ATTRIB	0x0008U			/* attributes changed */
+#define	NOTE_LINK	0x0010U			/* link count changed */
+#define	NOTE_RENAME	0x0020U			/* vnode was renamed */
+#define	NOTE_REVOKE	0x0040U			/* vnode access was revoked */
 
 /*
  * data/hint flags for EVFILT_PROC, shared with userspace
  */
-#define	NOTE_EXIT	0x80000000		/* process exited */
-#define	NOTE_FORK	0x40000000		/* process forked */
-#define	NOTE_EXEC	0x20000000		/* process exec'd */
-#define	NOTE_PCTRLMASK	0xf0000000		/* mask for hint bits */
-#define	NOTE_PDATAMASK	0x000fffff		/* mask for pid */
+#define	NOTE_EXIT	0x80000000U		/* process exited */
+#define	NOTE_FORK	0x40000000U		/* process forked */
+#define	NOTE_EXEC	0x20000000U		/* process exec'd */
+#define	NOTE_PCTRLMASK	0xf0000000U		/* mask for hint bits */
+#define	NOTE_PDATAMASK	0x000fffffU		/* mask for pid */
 
 /* additional flags for EVFILT_PROC */
-#define	NOTE_TRACK	0x00000001		/* follow across forks */
-#define	NOTE_TRACKERR	0x00000002		/* could not track child */
-#define	NOTE_CHILD	0x00000004		/* am a child process */
+#define	NOTE_TRACK	0x00000001U		/* follow across forks */
+#define	NOTE_TRACKERR	0x00000002U		/* could not track child */
+#define	NOTE_CHILD	0x00000004U		/* am a child process */
 
 /*
  * This is currently visible to userland to work around broken
@@ -151,7 +158,7 @@ struct kfilter_mapping {
  * Flag indicating hint is a signal.  Used by EVFILT_SIGNAL, and also
  * shared by EVFILT_PROC  (all knotes attached to p->p_klist)
  */
-#define	NOTE_SIGNAL	0x08000000
+#define	NOTE_SIGNAL	0x08000000U
 
 /*
  * Callback methods for each filter type.
@@ -181,19 +188,21 @@ struct knote {
 	TAILQ_ENTRY(knote)	kn_tqe;		/* q: for struct kqueue */
 	struct kqueue		*kn_kq;		/* q: which queue we are on */
 	struct kevent		kn_kevent;
-	uint32_t		kn_status;
-	uint32_t		kn_sfflags;	/*   saved filter flags */
-	uintptr_t		kn_sdata;	/*   saved data field */
-	void			*kn_obj;	/*   pointer to monitored obj */
+	uint32_t		kn_status;	/* q: flags below */
+	uint32_t		kn_sfflags;	/*    saved filter flags */
+	uintptr_t		kn_sdata;	/*    saved data field */
+	void			*kn_obj;	/*    monitored obj */
 	const struct filterops	*kn_fop;
 	struct kfilter		*kn_kfilter;
 	void 			*kn_hook;
 
-#define	KN_ACTIVE	0x01			/* event has been triggered */
-#define	KN_QUEUED	0x02			/* event is on queue */
-#define	KN_DISABLED	0x04			/* event is disabled */
-#define	KN_DETACHED	0x08			/* knote is detached */
-#define	KN_MARKER	0x10			/* is a marker */
+#define	KN_ACTIVE	0x01U			/* event has been triggered */
+#define	KN_QUEUED	0x02U			/* event is on queue */
+#define	KN_DISABLED	0x04U			/* event is disabled */
+#define	KN_DETACHED	0x08U			/* knote is detached */
+#define	KN_MARKER	0x10U			/* is a marker */
+#define	KN_BUSY		0x20U			/* is being scanned */
+/* Toggling KN_BUSY also requires kn_kq->kq_fdp->fd_lock. */
 
 #define	kn_id		kn_kevent.ident
 #define	kn_filter	kn_kevent.filter

Reply via email to