aboutsummaryrefslogtreecommitdiff
path: root/sys/miscfs
diff options
context:
space:
mode:
authorJonathan Lemon <jlemon@FreeBSD.org>2001-02-15 16:34:11 +0000
committerJonathan Lemon <jlemon@FreeBSD.org>2001-02-15 16:34:11 +0000
commit608a3ce62a98c42e5d415af6d6dc98f2bf4e615b (patch)
treea9aab1f038a4aab4a0d31919948c7c964e5b85d6 /sys/miscfs
parent2c9ba841c61cbced165336bd4e2b21be82cfdcd0 (diff)
downloadsrc-608a3ce62a98c42e5d415af6d6dc98f2bf4e615b.tar.gz
src-608a3ce62a98c42e5d415af6d6dc98f2bf4e615b.zip
Extend kqueue down to the device layer.
Backwards compatible approach suggested by: peter
Notes
Notes: svn path=/head/; revision=72521
Diffstat (limited to 'sys/miscfs')
-rw-r--r--sys/miscfs/fifofs/fifo_vnops.c66
-rw-r--r--sys/miscfs/specfs/spec_vnops.c19
2 files changed, 55 insertions, 30 deletions
diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c
index 453f2077bec7..79ee0aa7a3d9 100644
--- a/sys/miscfs/fifofs/fifo_vnops.c
+++ b/sys/miscfs/fifofs/fifo_vnops.c
@@ -71,21 +71,20 @@ static int fifo_read __P((struct vop_read_args *));
static int fifo_write __P((struct vop_write_args *));
static int fifo_ioctl __P((struct vop_ioctl_args *));
static int fifo_poll __P((struct vop_poll_args *));
+static int fifo_kqfilter __P((struct vop_kqfilter_args *));
static int fifo_bmap __P((struct vop_bmap_args *));
static int fifo_pathconf __P((struct vop_pathconf_args *));
static int fifo_advlock __P((struct vop_advlock_args *));
-static int filt_fiforattach(struct knote *kn);
static void filt_fifordetach(struct knote *kn);
static int filt_fiforead(struct knote *kn, long hint);
-static int filt_fifowattach(struct knote *kn);
static void filt_fifowdetach(struct knote *kn);
static int filt_fifowrite(struct knote *kn, long hint);
-struct filterops fifo_rwfiltops[] = {
- { 1, filt_fiforattach, filt_fifordetach, filt_fiforead },
- { 1, filt_fifowattach, filt_fifowdetach, filt_fifowrite },
-};
+static struct filterops fiforead_filtops =
+ { 1, NULL, filt_fifordetach, filt_fiforead };
+static struct filterops fifowrite_filtops =
+ { 1, NULL, filt_fifowdetach, filt_fifowrite };
vop_t **fifo_vnodeop_p;
static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
@@ -106,6 +105,7 @@ static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
{ &vop_open_desc, (vop_t *) fifo_open },
{ &vop_pathconf_desc, (vop_t *) fifo_pathconf },
{ &vop_poll_desc, (vop_t *) fifo_poll },
+ { &vop_kqfilter_desc, (vop_t *) fifo_kqfilter },
{ &vop_print_desc, (vop_t *) fifo_print },
{ &vop_read_desc, (vop_t *) fifo_read },
{ &vop_readdir_desc, (vop_t *) fifo_badop },
@@ -354,22 +354,42 @@ fifo_ioctl(ap)
return (0);
}
+/* ARGSUSED */
static int
-filt_fiforattach(struct knote *kn)
+fifo_kqfilter(ap)
+ struct vop_kqfilter_args /* {
+ struct vnode *a_vp;
+ struct knote *a_kn;
+ } */ *ap;
{
- struct vnode *vn = (struct vnode *)kn->kn_fp->f_data;
- struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock;
+ struct socket *so = (struct socket *)ap->a_vp->v_fifoinfo->fi_readsock;
+ struct sockbuf *sb;
+
+ switch (ap->a_kn->kn_filter) {
+ case EVFILT_READ:
+ ap->a_kn->kn_fop = &fiforead_filtops;
+ sb = &so->so_rcv;
+ break;
+ case EVFILT_WRITE:
+ ap->a_kn->kn_fop = &fifowrite_filtops;
+ sb = &so->so_snd;
+ break;
+ default:
+ return (1);
+ }
+
+ ap->a_kn->kn_hook = (caddr_t)so;
+
+ SLIST_INSERT_HEAD(&sb->sb_sel.si_note, ap->a_kn, kn_selnext);
+ sb->sb_flags |= SB_KNOTE;
- SLIST_INSERT_HEAD(&so->so_rcv.sb_sel.si_note, kn, kn_selnext);
- so->so_rcv.sb_flags |= SB_KNOTE;
return (0);
}
static void
filt_fifordetach(struct knote *kn)
{
- struct vnode *vn = (struct vnode *)kn->kn_fp->f_data;
- struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock;
+ struct socket *so = (struct socket *)kn->kn_hook;
SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext);
if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note))
@@ -379,8 +399,7 @@ filt_fifordetach(struct knote *kn)
static int
filt_fiforead(struct knote *kn, long hint)
{
- struct vnode *vn = (struct vnode *)kn->kn_fp->f_data;
- struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock;
+ struct socket *so = (struct socket *)kn->kn_hook;
kn->kn_data = so->so_rcv.sb_cc;
if (so->so_state & SS_CANTRCVMORE) {
@@ -391,22 +410,10 @@ filt_fiforead(struct knote *kn, long hint)
return (kn->kn_data > 0);
}
-static int
-filt_fifowattach(struct knote *kn)
-{
- struct vnode *vn = (struct vnode *)kn->kn_fp->f_data;
- struct socket *so = (struct socket *)vn->v_fifoinfo->fi_writesock;
-
- SLIST_INSERT_HEAD(&so->so_snd.sb_sel.si_note, kn, kn_selnext);
- so->so_rcv.sb_flags |= SB_KNOTE;
- return (0);
-}
-
static void
filt_fifowdetach(struct knote *kn)
{
- struct vnode *vn = (struct vnode *)kn->kn_fp->f_data;
- struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock;
+ struct socket *so = (struct socket *)kn->kn_hook;
SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext);
if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note))
@@ -416,8 +423,7 @@ filt_fifowdetach(struct knote *kn)
static int
filt_fifowrite(struct knote *kn, long hint)
{
- struct vnode *vn = (struct vnode *)kn->kn_fp->f_data;
- struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock;
+ struct socket *so = (struct socket *)kn->kn_hook;
kn->kn_data = sbspace(&so->so_snd);
if (so->so_state & SS_CANTSENDMORE) {
diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c
index dce82120cb4b..35a0a49f7bb7 100644
--- a/sys/miscfs/specfs/spec_vnops.c
+++ b/sys/miscfs/specfs/spec_vnops.c
@@ -62,6 +62,7 @@ static int spec_getpages __P((struct vop_getpages_args *));
static int spec_ioctl __P((struct vop_ioctl_args *));
static int spec_open __P((struct vop_open_args *));
static int spec_poll __P((struct vop_poll_args *));
+static int spec_kqfilter __P((struct vop_kqfilter_args *));
static int spec_print __P((struct vop_print_args *));
static int spec_read __P((struct vop_read_args *));
static int spec_strategy __P((struct vop_strategy_args *));
@@ -87,6 +88,7 @@ static struct vnodeopv_entry_desc spec_vnodeop_entries[] = {
{ &vop_open_desc, (vop_t *) spec_open },
{ &vop_pathconf_desc, (vop_t *) vop_stdpathconf },
{ &vop_poll_desc, (vop_t *) spec_poll },
+ { &vop_kqfilter_desc, (vop_t *) spec_kqfilter },
{ &vop_print_desc, (vop_t *) spec_print },
{ &vop_read_desc, (vop_t *) spec_read },
{ &vop_readdir_desc, (vop_t *) vop_panic },
@@ -330,6 +332,23 @@ spec_poll(ap)
dev = ap->a_vp->v_rdev;
return (*devsw(dev)->d_poll)(dev, ap->a_events, ap->a_p);
}
+
+/* ARGSUSED */
+static int
+spec_kqfilter(ap)
+ struct vop_kqfilter_args /* {
+ struct vnode *a_vp;
+ struct knote *a_kn;
+ } */ *ap;
+{
+ dev_t dev;
+
+ dev = ap->a_vp->v_rdev;
+ if (devsw(dev)->d_flags & D_KQFILTER)
+ return (*devsw(dev)->d_kqfilter)(dev, ap->a_kn);
+ return (1);
+}
+
/*
* Synch buffers associated with a block device
*/