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