Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-8]: src/sys Pull up following revision(s) (requested by christos ...



details:   https://anonhg.NetBSD.org/src/rev/3d98d429b6a7
branches:  netbsd-8
changeset: 434076:3d98d429b6a7
user:      snj <snj%NetBSD.org@localhost>
date:      Wed Jul 05 20:04:40 2017 +0000

description:
Pull up following revision(s) (requested by christos in ticket #91):
        sys/kern/kern_event.c: revision 1.92
        sys/miscfs/genfs/genfs_vnops.c: revision 1.198
        sys/sys/event.h: revision 1.30
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

diffstat:

 sys/kern/kern_event.c          |  31 +++++++++++++++++++++++--------
 sys/miscfs/genfs/genfs_vnops.c |  35 +++++++++++++++++++++++++++++++++--
 sys/sys/event.h                |  13 +++++++------
 3 files changed, 63 insertions(+), 16 deletions(-)

diffs (208 lines):

diff -r 86628c24a468 -r 3d98d429b6a7 sys/kern/kern_event.c
--- a/sys/kern/kern_event.c     Wed Jul 05 20:02:27 2017 +0000
+++ b/sys/kern/kern_event.c     Wed Jul 05 20:04:40 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_event.c,v 1.91 2017/05/11 23:50:17 christos Exp $ */
+/*     $NetBSD: kern_event.c,v 1.91.2.1 2017/07/05 20:04:40 snj Exp $  */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.91 2017/05/11 23:50:17 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.91.2.1 2017/07/05 20:04:40 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1021,8 +1021,9 @@
                        if (error != 0) {
 #ifdef DIAGNOSTIC
                                
-                               printf("%s: event not supported for file type"
-                                   " %d (error %d)\n", __func__, kn->kn_obj ?
+                               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 */
@@ -1204,10 +1205,19 @@
                                        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) {
@@ -1218,6 +1228,7 @@
                                            (timeout = gettimeleft(&ats,
                                            &sleepts)) <= 0))
                                                goto done;
+                                       mutex_exit(&fdp->fd_lock);
                                        goto retry;
                                }
                                /* someone else's marker. */
@@ -1239,6 +1250,7 @@
                                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);
@@ -1261,10 +1273,10 @@
                        nkev++;
                        if (kn->kn_flags & EV_ONESHOT) {
                                /* delete ONESHOT events after retrieval */
+                               kn->kn_status &= ~KN_BUSY;
                                mutex_spin_exit(&kq->kq_lock);
+                               knote_detach(kn, fdp, true);
                                mutex_enter(&fdp->fd_lock);
-                               kn->kn_status &= ~KN_BUSY;
-                               knote_detach(kn, fdp, true);
                                mutex_spin_enter(&kq->kq_lock);
                        } else if (kn->kn_flags & EV_CLEAR) {
                                /* clear state after retrieval */
@@ -1286,9 +1298,11 @@
                        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;
@@ -1301,9 +1315,10 @@
                                break;
                        }
                }
+ done:
+               mutex_spin_exit(&kq->kq_lock);
+               mutex_exit(&fdp->fd_lock);
        }
- done:
-       mutex_spin_exit(&kq->kq_lock);
        if (nkev != 0) {
                /* copyout remaining events */
                error = (*keops->keo_put_events)(keops->keo_private,
diff -r 86628c24a468 -r 3d98d429b6a7 sys/miscfs/genfs/genfs_vnops.c
--- a/sys/miscfs/genfs/genfs_vnops.c    Wed Jul 05 20:02:27 2017 +0000
+++ b/sys/miscfs/genfs/genfs_vnops.c    Wed Jul 05 20:04:40 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: genfs_vnops.c,v 1.195.4.1 2017/06/04 20:35:01 bouyer Exp $     */
+/*     $NetBSD: genfs_vnops.c,v 1.195.4.2 2017/07/05 20:04:40 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.195.4.1 2017/06/04 20:35:01 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.195.4.2 2017/07/05 20:04:40 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -500,6 +500,32 @@
 }
 
 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;
@@ -530,6 +556,8 @@
 
 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 };
 
@@ -549,6 +577,9 @@
        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;
diff -r 86628c24a468 -r 3d98d429b6a7 sys/sys/event.h
--- a/sys/sys/event.h   Wed Jul 05 20:02:27 2017 +0000
+++ b/sys/sys/event.h   Wed Jul 05 20:04:40 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: event.h,v 1.28 2017/06/02 19:44:06 kamil Exp $ */
+/*     $NetBSD: event.h,v 1.28.2.1 2017/07/05 20:04:40 snj Exp $       */
 
 /*-
  * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon%FreeBSD.org@localhost>
@@ -187,10 +187,10 @@
        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;
@@ -200,7 +200,8 @@
 #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 */
+#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



Home | Main Index | Thread Index | Old Index