summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2020-06-08 08:04:11 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2020-06-08 08:04:11 +0000
commit77ac5fee71b6b751fa92e0f54c139279ab597df6 (patch)
treed78a144f1a3dc5e44e5579f24a3038a19f9904c0
parent999f0686e0633f8b7bb9b76a14e47f5c20d2ea36 (diff)
Use a new EV_OLDAPI flag to match the behavior of poll(2) and select(2).
Adapt FS kqfilters to always return true when the flag is set and bypass the polling mechanism of the NFS thread. While here implement a write filter for NFS. ok visa@
-rw-r--r--sys/isofs/cd9660/cd9660_vnops.c5
-rw-r--r--sys/miscfs/fuse/fuse_vnops.c5
-rw-r--r--sys/msdosfs/msdosfs_vnops.c6
-rw-r--r--sys/nfs/nfs_kq.c73
-rw-r--r--sys/sys/event.h3
-rw-r--r--sys/tmpfs/tmpfs_vnops.c5
-rw-r--r--sys/ufs/ufs/ufs_vnops.c5
7 files changed, 87 insertions, 15 deletions
diff --git a/sys/isofs/cd9660/cd9660_vnops.c b/sys/isofs/cd9660/cd9660_vnops.c
index f1d43c64bd0..c1abbb92ee7 100644
--- a/sys/isofs/cd9660/cd9660_vnops.c
+++ b/sys/isofs/cd9660/cd9660_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cd9660_vnops.c,v 1.83 2020/04/07 13:27:51 visa Exp $ */
+/* $OpenBSD: cd9660_vnops.c,v 1.84 2020/06/08 08:04:09 mpi Exp $ */
/* $NetBSD: cd9660_vnops.c,v 1.42 1997/10/16 23:56:57 christos Exp $ */
/*-
@@ -1036,6 +1036,9 @@ filt_cd9660read(struct knote *kn, long hint)
return (1);
}
+ if (kn->kn_flags & EV_OLDAPI)
+ return (1);
+
return (kn->kn_data != 0);
}
diff --git a/sys/miscfs/fuse/fuse_vnops.c b/sys/miscfs/fuse/fuse_vnops.c
index 6438cecd1c9..ab443aa1078 100644
--- a/sys/miscfs/fuse/fuse_vnops.c
+++ b/sys/miscfs/fuse/fuse_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_vnops.c,v 1.59 2020/04/07 13:27:51 visa Exp $ */
+/* $OpenBSD: fuse_vnops.c,v 1.60 2020/06/08 08:04:09 mpi Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -188,6 +188,9 @@ filt_fusefsread(struct knote *kn, long hint)
return (1);
}
+ if (kn->kn_flags & EV_OLDAPI)
+ return (1);
+
return (kn->kn_data != 0);
}
diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c
index fc46268052e..ae939b18649 100644
--- a/sys/msdosfs/msdosfs_vnops.c
+++ b/sys/msdosfs/msdosfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: msdosfs_vnops.c,v 1.132 2020/04/07 13:27:52 visa Exp $ */
+/* $OpenBSD: msdosfs_vnops.c,v 1.133 2020/06/08 08:04:09 mpi Exp $ */
/* $NetBSD: msdosfs_vnops.c,v 1.63 1997/10/17 11:24:19 ws Exp $ */
/*-
@@ -2013,6 +2013,10 @@ filt_msdosfsread(struct knote *kn, long hint)
kn->kn_fflags |= NOTE_EOF;
return (1);
}
+
+ if (kn->kn_flags & EV_OLDAPI)
+ return (1);
+
return (kn->kn_data != 0);
}
diff --git a/sys/nfs/nfs_kq.c b/sys/nfs/nfs_kq.c
index f43211e76c3..f8ed9f76d5d 100644
--- a/sys/nfs/nfs_kq.c
+++ b/sys/nfs/nfs_kq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_kq.c,v 1.30 2020/04/07 13:27:52 visa Exp $ */
+/* $OpenBSD: nfs_kq.c,v 1.31 2020/06/08 08:04:10 mpi Exp $ */
/* $NetBSD: nfs_kq.c,v 1.7 2003/10/30 01:43:10 simonb Exp $ */
/*-
@@ -50,9 +50,12 @@
#include <nfs/nfs_var.h>
void nfs_kqpoll(void *);
+int nfs_kqwatch(struct vnode *);
+void nfs_kqunwatch(struct vnode *);
void filt_nfsdetach(struct knote *);
int filt_nfsread(struct knote *, long);
+int filt_nfswrite(struct knote *, long);
int filt_nfsvnode(struct knote *, long);
struct kevq {
@@ -182,11 +185,19 @@ void
filt_nfsdetach(struct knote *kn)
{
struct vnode *vp = (struct vnode *)kn->kn_hook;
- struct kevq *ke;
klist_remove(&vp->v_selectinfo.si_note, kn);
/* Remove the vnode from watch list */
+ if ((kn->kn_flags & EV_OLDAPI) == 0)
+ nfs_kqunwatch(vp);
+}
+
+void
+nfs_kqunwatch(struct vnode *vp)
+{
+ struct kevq *ke;
+
rw_enter_write(&nfskevq_lock);
SLIST_FOREACH(ke, &kevlist, kev_link) {
if (ke->vp == vp) {
@@ -234,10 +245,30 @@ filt_nfsread(struct knote *kn, long hint)
kn->kn_fflags |= NOTE_EOF;
return (1);
}
+
+ if (kn->kn_flags & EV_OLDAPI)
+ return (1);
+
return (kn->kn_data != 0);
}
int
+filt_nfswrite(struct knote *kn, long hint)
+{
+ /*
+ * filesystem is gone, so set the EOF flag and schedule
+ * the knote for deletion.
+ */
+ if (hint == NOTE_REVOKE) {
+ kn->kn_flags |= (EV_EOF | EV_ONESHOT);
+ return (1);
+ }
+
+ kn->kn_data = 0;
+ return (1);
+}
+
+int
filt_nfsvnode(struct knote *kn, long hint)
{
if (kn->kn_sfflags & hint)
@@ -256,6 +287,13 @@ static const struct filterops nfsread_filtops = {
.f_event = filt_nfsread,
};
+static const struct filterops nfswrite_filtops = {
+ .f_flags = FILTEROP_ISFD,
+ .f_attach = NULL,
+ .f_detach = filt_nfsdetach,
+ .f_event = filt_nfswrite,
+};
+
static const struct filterops nfsvnode_filtops = {
.f_flags = FILTEROP_ISFD,
.f_attach = NULL,
@@ -269,10 +307,6 @@ nfs_kqfilter(void *v)
struct vop_kqfilter_args *ap = v;
struct vnode *vp;
struct knote *kn;
- struct kevq *ke;
- int error = 0;
- struct vattr attr;
- struct proc *p = curproc; /* XXX */
vp = ap->a_vp;
kn = ap->a_kn;
@@ -286,6 +320,9 @@ nfs_kqfilter(void *v)
case EVFILT_READ:
kn->kn_fop = &nfsread_filtops;
break;
+ case EVFILT_WRITE:
+ kn->kn_fop = &nfswrite_filtops;
+ break;
case EVFILT_VNODE:
kn->kn_fop = &nfsvnode_filtops;
break;
@@ -298,7 +335,27 @@ nfs_kqfilter(void *v)
/*
* Put the vnode to watched list.
*/
-
+ if ((kn->kn_flags & EV_OLDAPI) == 0) {
+ int error;
+
+ error = nfs_kqwatch(vp);
+ if (error)
+ return (error);
+ }
+
+ klist_insert(&vp->v_selectinfo.si_note, kn);
+
+ return (0);
+}
+
+int
+nfs_kqwatch(struct vnode *vp)
+{
+ struct proc *p = curproc; /* XXX */
+ struct vattr attr;
+ struct kevq *ke;
+ int error = 0;
+
/*
* Fetch current attributes. It's only needed when the vnode
* is not watched yet, but we need to do this without lock
@@ -339,8 +396,6 @@ nfs_kqfilter(void *v)
/* kick the poller */
wakeup(pnfskq);
- klist_insert(&vp->v_selectinfo.si_note, kn);
-
out:
rw_exit_write(&nfskevq_lock);
return (error);
diff --git a/sys/sys/event.h b/sys/sys/event.h
index e9247b9cd93..a5000398a8f 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: event.h,v 1.38 2020/05/25 15:54:10 visa Exp $ */
+/* $OpenBSD: event.h,v 1.39 2020/06/08 08:04:10 mpi Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -74,6 +74,7 @@ struct kevent {
#define EV_DISPATCH 0x0080 /* disable event after reporting */
#define EV_SYSFLAGS 0xF000 /* reserved by system */
+#define EV_OLDAPI 0x1000 /* match behavior of poll & select */
#define EV_FLAG1 0x2000 /* filter-specific flag */
/* returned values */
diff --git a/sys/tmpfs/tmpfs_vnops.c b/sys/tmpfs/tmpfs_vnops.c
index c7a40d10333..46a2c1c0d0a 100644
--- a/sys/tmpfs/tmpfs_vnops.c
+++ b/sys/tmpfs/tmpfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmpfs_vnops.c,v 1.40 2020/04/07 13:27:52 visa Exp $ */
+/* $OpenBSD: tmpfs_vnops.c,v 1.41 2020/06/08 08:04:10 mpi Exp $ */
/* $NetBSD: tmpfs_vnops.c,v 1.100 2012/11/05 17:27:39 dholland Exp $ */
/*
@@ -2665,6 +2665,9 @@ filt_tmpfsread(struct knote *kn, long hint)
return (1);
}
+ if (kn->kn_flags & EV_OLDAPI)
+ return (1);
+
return (kn->kn_data != 0);
}
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index a651fa9f065..4dda026bd09 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_vnops.c,v 1.150 2020/04/07 13:27:52 visa Exp $ */
+/* $OpenBSD: ufs_vnops.c,v 1.151 2020/06/08 08:04:10 mpi Exp $ */
/* $NetBSD: ufs_vnops.c,v 1.18 1996/05/11 18:28:04 mycroft Exp $ */
/*
@@ -1973,6 +1973,9 @@ filt_ufsread(struct knote *kn, long hint)
return (1);
}
+ if (kn->kn_flags & EV_OLDAPI)
+ return (1);
+
return (kn->kn_data != 0);
}