diff options
author | jlemon <jlemon@FreeBSD.org> | 2001-02-15 16:34:11 +0000 |
---|---|---|
committer | jlemon <jlemon@FreeBSD.org> | 2001-02-15 16:34:11 +0000 |
commit | 11781a7431fab609cd00058a63ac09ccddb16854 (patch) | |
tree | ee46dbf40488c941cf17b05e69bfe21e4f2d7128 /sys/fs | |
parent | 5655168b87e22a331c5fc3b603901647ff90b2e4 (diff) | |
download | FreeBSD-src-11781a7431fab609cd00058a63ac09ccddb16854.zip FreeBSD-src-11781a7431fab609cd00058a63ac09ccddb16854.tar.gz |
Extend kqueue down to the device layer.
Backwards compatible approach suggested by: peter
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/fifofs/fifo_vnops.c | 66 | ||||
-rw-r--r-- | sys/fs/specfs/spec_vnops.c | 19 |
2 files changed, 55 insertions, 30 deletions
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c index 453f207..79ee0aa 100644 --- a/sys/fs/fifofs/fifo_vnops.c +++ b/sys/fs/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/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c index dce8212..35a0a49 100644 --- a/sys/fs/specfs/spec_vnops.c +++ b/sys/fs/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 */ |