diff options
author | Niels Provos <provos@cvs.openbsd.org> | 2001-03-01 20:54:37 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 2001-03-01 20:54:37 +0000 |
commit | 950a6333d90c04783291b2f77e89257bc6df966e (patch) | |
tree | 0d452c7deda41df938a0f8d009e3f850249b8eb8 /sys/kern | |
parent | 9027db9730b3cc9c6f973b4e6fbdf6b353260158 (diff) |
port kqueue changes from freebsd, plus all required openbsd glue.
okay deraadt@, millert@
from jlemon@freebsd.org:
extend kqueue down to the device layer, backwards compatible approach
suggested by peter@freebsd.org
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_event.c | 150 | ||||
-rw-r--r-- | sys/kern/spec_vnops.c | 21 | ||||
-rw-r--r-- | sys/kern/sys_pipe.c | 32 | ||||
-rw-r--r-- | sys/kern/sys_socket.c | 8 | ||||
-rw-r--r-- | sys/kern/tty.c | 91 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 60 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 87 | ||||
-rw-r--r-- | sys/kern/vnode_if.src | 10 |
8 files changed, 254 insertions, 205 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index d407ba8ad27..5e7ea093237 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -1,7 +1,7 @@ -/* $OpenBSD: kern_event.c,v 1.6 2000/11/21 21:49:57 provos Exp $ */ +/* $OpenBSD: kern_event.c,v 1.7 2001/03/01 20:54:33 provos Exp $ */ /*- - * Copyright (c) 1999,2000 Jonathan Lemon <jlemon@FreeBSD.org> + * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/kern/kern_event.c,v 1.15 2000/08/07 16:45:42 jlemon Exp $ + * $FreeBSD: src/sys/kern/kern_event.c,v 1.22 2001/02/23 20:32:42 jlemon Exp $ */ #include <sys/param.h> @@ -49,15 +49,6 @@ #include <sys/mount.h> #include <sys/syscallargs.h> -int filt_nullattach(struct knote *kn); -int filt_rwtypattach(struct knote *kn); -int filt_kqattach(struct knote *kn); -void filt_kqdetach(struct knote *kn); -int filt_kqueue(struct knote *kn, long hint); -int filt_procattach(struct knote *kn); -void filt_procdetach(struct knote *kn); -int filt_proc(struct knote *kn, long hint); - int kqueue_scan(struct file *fp, int maxevents, struct kevent *ulistp, const struct timespec *timeout, struct proc *p, int *retval); @@ -69,9 +60,19 @@ int kqueue_write(struct file *fp, off_t *poff, struct uio *uio, int kqueue_ioctl(struct file *fp, u_long com, caddr_t data, struct proc *p); int kqueue_select(struct file *fp, int which, struct proc *p); +int kqueue_kqfilter(struct file *fp, struct knote *kn); int kqueue_close(struct file *fp, struct proc *p); void kqueue_wakeup(struct kqueue *kq); +struct fileops kqueueops = { + kqueue_read, + kqueue_write, + kqueue_ioctl, + kqueue_select, + kqueue_kqfilter, + kqueue_close +}; + void knote_attach(struct knote *kn, struct filedesc *fdp); void knote_drop(struct knote *kn, struct proc *p); void knote_enqueue(struct knote *kn); @@ -79,6 +80,20 @@ void knote_dequeue(struct knote *kn); struct knote *knote_alloc(void); void knote_free(struct knote *kn); +void filt_kqdetach(struct knote *kn); +int filt_kqueue(struct knote *kn, long hint); +int filt_procattach(struct knote *kn); +void filt_procdetach(struct knote *kn); +int filt_proc(struct knote *kn, long hint); +int filt_fileattach(struct knote *kn); + +struct filterops kqread_filtops = + { 1, NULL, filt_kqdetach, filt_kqueue }; +struct filterops proc_filtops = + { 0, filt_procattach, filt_procdetach, filt_proc }; +struct filterops file_filtops = + { 1, filt_fileattach, NULL, NULL }; + #define KNOTE_ACTIVATE(kn) do { \ kn->kn_status |= KN_ACTIVE; \ if ((kn->kn_status & (KN_QUEUED | KN_DISABLED)) == 0) \ @@ -88,88 +103,40 @@ void knote_free(struct knote *kn); #define KN_HASHSIZE 64 /* XXX should be tunable */ #define KN_HASH(val, mask) (((val) ^ (val >> 8)) & (mask)) -struct fileops kqueueops = { - kqueue_read, - kqueue_write, - kqueue_ioctl, - kqueue_select, - kqueue_close -}; - -extern struct filterops so_rwfiltops[]; -extern struct filterops pipe_rwfiltops[]; -#ifdef notyet -extern struct filterops fifo_rwfiltops[]; -#endif -extern struct filterops vn_rwfiltops[]; - -struct filterops kq_rwfiltops[] = { - { 1, filt_kqattach, filt_kqdetach, filt_kqueue }, - { 1, filt_nullattach, NULL, NULL }, -}; - extern struct filterops sig_filtops; #ifdef notyet extern struct filterops aio_filtops; #endif -extern struct filterops vn_filtops; - -struct filterops rwtype_filtops = - { 1, filt_rwtypattach, NULL, NULL }; -struct filterops proc_filtops = - { 0, filt_procattach, filt_procdetach, filt_proc }; /* - * XXX - * These must match the order of defines in <sys/file.h> - */ -struct filterops *rwtypfilt_sw[] = { - NULL, /* 0 */ - vn_rwfiltops, /* DTYPE_VNODE */ - so_rwfiltops, /* DTYPE_SOCKET */ - pipe_rwfiltops, /* DTYPE_PIPE */ - /* fifo_rwfiltops, */ /* DTYPE_FIFO */ - kq_rwfiltops, /* DTYPE_KQUEUE */ -}; - -/* - * table for all system-defined filters. + * Table for for all system-defined filters. */ struct filterops *sysfilt_ops[] = { - &rwtype_filtops, /* EVFILT_READ */ - &rwtype_filtops, /* EVFILT_WRITE */ + &file_filtops, /* EVFILT_READ */ + &file_filtops, /* EVFILT_WRITE */ NULL, /*&aio_filtops,*/ /* EVFILT_AIO */ - &vn_filtops, /* EVFILT_VNODE */ + &file_filtops, /* EVFILT_VNODE */ &proc_filtops, /* EVFILT_PROC */ &sig_filtops, /* EVFILT_SIGNAL */ }; int -filt_nullattach(struct knote *kn) -{ - return (ENXIO); -} - -/* - * file-type specific attach routine for read/write filters - */ -int -filt_rwtypattach(struct knote *kn) +filt_fileattach(struct knote *kn) { - struct filterops *fops; + struct file *fp = kn->kn_fp; - fops = rwtypfilt_sw[kn->kn_fp->f_type]; - if (fops == NULL) - return (EINVAL); - kn->kn_fop = &fops[~kn->kn_filter]; /* convert to 0-base index */ - return (kn->kn_fop->f_attach(kn)); + return ((*fp->f_ops->fo_kqfilter)(fp, kn)); } int -filt_kqattach(struct knote *kn) +kqueue_kqfilter(struct file *fp, struct knote *kn) { struct kqueue *kq = (struct kqueue *)kn->kn_fp->f_data; + if (kn->kn_filter != EVFILT_READ) + return (1); + + kn->kn_fop = &kqread_filtops; SLIST_INSERT_HEAD(&kq->kq_sel.si_note, kn, kn_selnext); return (0); } @@ -338,7 +305,7 @@ sys_kevent(struct proc *p, void *v, register_t *retval) } */ *uap = v; struct kevent *kevp; struct kqueue *kq; - struct file *fp; + struct file *fp = NULL; struct timespec ts; int i, n, nerrors, error; @@ -347,10 +314,12 @@ sys_kevent(struct proc *p, void *v, register_t *retval) (fp->f_type != DTYPE_KQUEUE)) return (EBADF); + fp->f_count++; + if (SCARG(uap, timeout) != NULL) { error = copyin(SCARG(uap, timeout), &ts, sizeof(ts)); if (error) - return error; + goto done; SCARG(uap, timeout) = &ts; } @@ -363,7 +332,7 @@ sys_kevent(struct proc *p, void *v, register_t *retval) error = copyin(SCARG(uap, changelist), kq->kq_kev, n * sizeof(struct kevent)); if (error) - return (error); + goto done; for (i = 0; i < n; i++) { kevp = &kq->kq_kev[i]; kevp->flags &= ~EV_SYSFLAGS; @@ -379,7 +348,7 @@ sys_kevent(struct proc *p, void *v, register_t *retval) SCARG(uap, nevents)--; nerrors++; } else { - return (error); + goto done; } } } @@ -388,12 +357,16 @@ sys_kevent(struct proc *p, void *v, register_t *retval) } if (nerrors) { *retval = nerrors; - return (0); + error = 0; + goto done; } error = kqueue_scan(fp, SCARG(uap, nevents), SCARG(uap, eventlist), SCARG(uap, timeout), p, &n); *retval = n; + done: + if (fp != NULL) + closef(fp, p); return (error); } @@ -427,6 +400,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p) if ((u_int)kev->ident >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[kev->ident]) == NULL) return (EBADF); + fp->f_count++; if (kev->ident < fdp->fd_knlistsize) { SLIST_FOREACH(kn, &fdp->fd_knlist[kev->ident], kn_link) @@ -448,8 +422,10 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p) } } - if (kn == NULL && ((kev->flags & EV_ADD) == 0)) - return (ENOENT); + if (kn == NULL && ((kev->flags & EV_ADD) == 0)) { + error = ENOENT; + goto done; + } /* * kn now contains the matching knote, or NULL if no match @@ -458,14 +434,20 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p) if (kn == NULL) { kn = knote_alloc(); - if (kn == NULL) - return (ENOMEM); - if (fp != NULL) - fp->f_count++; + if (kn == NULL) { + error = ENOMEM; + goto done; + } kn->kn_fp = fp; kn->kn_kq = kq; kn->kn_fop = fops; + /* + * apply reference count to knote structure, and + * do not release it at the end of this routine. + */ + fp = NULL; + kn->kn_sfflags = kev->fflags; kn->kn_sdata = kev->data; kev->fflags = 0; @@ -516,6 +498,8 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p) } done: + if (fp != NULL) + closef(fp, p); return (error); } diff --git a/sys/kern/spec_vnops.c b/sys/kern/spec_vnops.c index 5d6281fc865..b241aed4e27 100644 --- a/sys/kern/spec_vnops.c +++ b/sys/kern/spec_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: spec_vnops.c,v 1.17 2001/02/24 19:07:10 csapuntz Exp $ */ +/* $OpenBSD: spec_vnops.c,v 1.18 2001/03/01 20:54:35 provos Exp $ */ /* $NetBSD: spec_vnops.c,v 1.29 1996/04/22 01:42:38 christos Exp $ */ /* @@ -81,6 +81,7 @@ struct vnodeopv_entry_desc spec_vnodeop_entries[] = { { &vop_lease_desc, spec_lease_check }, /* lease */ { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ { &vop_select_desc, spec_select }, /* select */ + { &vop_kqfilter_desc, spec_kqfilter }, /* kqfilter */ { &vop_revoke_desc, spec_revoke }, /* revoke */ { &vop_mmap_desc, spec_mmap }, /* mmap */ { &vop_fsync_desc, spec_fsync }, /* fsync */ @@ -472,6 +473,24 @@ spec_select(v) return (*cdevsw[major(dev)].d_select)(dev, ap->a_which, ap->a_p); } } +/* ARGSUSED */ +int +spec_kqfilter(v) + void *v; +{ + struct vop_kqfilter_args /* { + struct vnode *a_vp; + struct knote *a_kn; + } */ *ap = v; + + dev_t dev; + + dev = ap->a_vp->v_rdev; + if (cdevsw[major(dev)].d_type & D_KQFILTER) + return (*cdevsw[major(dev)].d_kqfilter)(dev, ap->a_kn); + return (1); +} + /* * Synch buffers associated with a block device */ diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 28dfd3dc210..cfbb2efcd2e 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_pipe.c,v 1.25 2000/11/16 20:02:17 provos Exp $ */ +/* $OpenBSD: sys_pipe.c,v 1.26 2001/03/01 20:54:33 provos Exp $ */ /* * Copyright (c) 1996 John S. Dyson @@ -67,21 +67,24 @@ int pipe_read __P((struct file *, off_t *, struct uio *, struct ucred *)); int pipe_write __P((struct file *, off_t *, struct uio *, struct ucred *)); int pipe_close __P((struct file *, struct proc *)); int pipe_select __P((struct file *, int which, struct proc *)); +int pipe_kqfilter __P((struct file *fp, struct knote *kn)); int pipe_ioctl __P((struct file *, u_long, caddr_t, struct proc *)); -static struct fileops pipeops = - { pipe_read, pipe_write, pipe_ioctl, pipe_select, pipe_close }; +static struct fileops pipeops = { + pipe_read, pipe_write, pipe_ioctl, pipe_select, pipe_kqfilter, + pipe_close +}; -int filt_pipeattach(struct knote *kn); void filt_pipedetach(struct knote *kn); int filt_piperead(struct knote *kn, long hint); int filt_pipewrite(struct knote *kn, long hint); -struct filterops pipe_rwfiltops[] = { - { 1, filt_pipeattach, filt_pipedetach, filt_piperead }, - { 1, filt_pipeattach, filt_pipedetach, filt_pipewrite }, -}; +struct filterops pipe_rfiltops = + { 1, NULL, filt_pipedetach, filt_piperead }; +struct filterops pipe_wfiltops = + { 1, NULL, filt_pipedetach, filt_pipewrite }; + /* * Default pipe buffer size(s), this can be kind-of large now because pipe * space is pageable. The pipe code will try to maintain locality of @@ -758,10 +761,21 @@ pipeclose(cpipe) #endif int -filt_pipeattach(struct knote *kn) +pipe_kqfilter(struct file *fp, struct knote *kn) { struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &pipe_rfiltops; + break; + case EVFILT_WRITE: + kn->kn_fop = &pipe_wfiltops; + break; + default: + return (1); + } + SLIST_INSERT_HEAD(&rpipe->pipe_sel.si_note, kn, kn_selnext); return (0); } diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index f385310036a..1d51c9349fa 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_socket.c,v 1.4 2000/04/19 08:34:53 csapuntz Exp $ */ +/* $OpenBSD: sys_socket.c,v 1.5 2001/03/01 20:54:34 provos Exp $ */ /* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */ /* @@ -50,8 +50,10 @@ #include <net/if.h> #include <net/route.h> -struct fileops socketops = - { soo_read, soo_write, soo_ioctl, soo_select, soo_close }; +struct fileops socketops = { + soo_read, soo_write, soo_ioctl, soo_select, soo_kqfilter, + soo_close +}; /* ARGSUSED */ int diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 1a7990146d1..3437a0537dc 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.41 2000/07/19 13:37:28 art Exp $ */ +/* $OpenBSD: tty.c,v 1.42 2001/03/01 20:54:34 provos Exp $ */ /* $NetBSD: tty.c,v 1.68.4.2 1996/06/06 16:04:52 thorpej Exp $ */ /*- @@ -70,6 +70,10 @@ void ttyunblock __P((struct tty *)); static void ttyecho __P((int, struct tty *)); static void ttyrubo __P((struct tty *, int)); static int proc_compare __P((struct proc *, struct proc *)); +int filt_ttyread __P((struct knote *kn, long hint)); +void filt_ttyrdetach __P((struct knote *kn)); +int filt_ttywrite __P((struct knote *kn, long hint)); +void filt_ttywdetach __P((struct knote *kn)); /* Symbolic sleep message strings. */ char ttclos[] = "ttycls"; @@ -1049,6 +1053,90 @@ win: splx(s); return (0); } +struct filterops ttyread_filtops = + { 1, NULL, filt_ttyrdetach, filt_ttyread }; +struct filterops ttywrite_filtops = + { 1, NULL, filt_ttywdetach, filt_ttywrite }; + +int +ttkqfilter(dev, kn) + dev_t dev; + struct knote *kn; +{ + struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev); + struct klist *klist; + int s; + + switch (kn->kn_filter) { + case EVFILT_READ: + klist = &tp->t_rsel.si_note; + kn->kn_fop = &ttyread_filtops; + break; + case EVFILT_WRITE: + klist = &tp->t_wsel.si_note; + kn->kn_fop = &ttywrite_filtops; + break; + default: + return (1); + } + + kn->kn_hook = (caddr_t)dev; + + s = spltty(); + SLIST_INSERT_HEAD(klist, kn, kn_selnext); + splx(s); + + return (0); +} + +void +filt_ttyrdetach(struct knote *kn) +{ + dev_t dev = (dev_t)kn->kn_hook; + struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev); + int s = spltty(); + + SLIST_REMOVE(&tp->t_rsel.si_note, kn, knote, kn_selnext); + splx(s); +} + +int +filt_ttyread(struct knote *kn, long hint) +{ + dev_t dev = (dev_t)kn->kn_hook; + struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev); + + kn->kn_data = ttnread(tp); + if (!ISSET(tp->t_state, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) { + kn->kn_flags |= EV_EOF; + return (1); + } + return (kn->kn_data > 0); +} + +void +filt_ttywdetach(struct knote *kn) +{ + dev_t dev = (dev_t)kn->kn_hook; + struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev); + int s = spltty(); + + SLIST_REMOVE(&tp->t_wsel.si_note, kn, knote, kn_selnext); + splx(s); +} + +int +filt_ttywrite(kn, hint) + struct knote *kn; + long hint; +{ + dev_t dev = (dev_t)kn->kn_hook; + struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev); + + kn->kn_data = tp->t_outq.c_cc; + return (kn->kn_data <= tp->t_lowat); +} + static int ttnread(tp) struct tty *tp; @@ -1935,6 +2023,7 @@ ttwakeup(tp) if (ISSET(tp->t_state, TS_ASYNC)) pgsignal(tp->t_pgrp, SIGIO, 1); wakeup((caddr_t)&tp->t_rawq); + KNOTE(&tp->t_rsel.si_note, 0); } /* diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 8b36265424e..207f52feade 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.30 2001/02/07 12:20:42 itojun Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.31 2001/03/01 20:54:34 provos Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -51,21 +51,19 @@ #include <sys/signalvar.h> #include <sys/resourcevar.h> -int filt_sorattach(struct knote *kn); void filt_sordetach(struct knote *kn); int filt_soread(struct knote *kn, long hint); -int filt_sowattach(struct knote *kn); void filt_sowdetach(struct knote *kn); int filt_sowrite(struct knote *kn, long hint); int filt_solisten(struct knote *kn, long hint); struct filterops solisten_filtops = - { 1, filt_sorattach, filt_sordetach, filt_solisten }; + { 1, NULL, filt_sordetach, filt_solisten }; +struct filterops soread_filtops = + { 1, NULL, filt_sordetach, filt_soread }; +struct filterops sowrite_filtops = + { 1, NULL, filt_sowdetach, filt_sowrite }; -struct filterops so_rwfiltops[] = { - { 1, filt_sorattach, filt_sordetach, filt_soread }, - { 1, filt_sowattach, filt_sowdetach, filt_sowrite }, -}; #ifndef SOMINCONN #define SOMINCONN 80 @@ -1114,15 +1112,31 @@ sohasoutofband(so) } int -filt_sorattach(struct knote *kn) +soo_kqfilter(struct file *fp, struct knote *kn) { struct socket *so = (struct socket *)kn->kn_fp->f_data; - int s = splnet(); + struct sockbuf *sb; + int s; - if (so->so_options & SO_ACCEPTCONN) - kn->kn_fop = &solisten_filtops; - SLIST_INSERT_HEAD(&so->so_rcv.sb_sel.si_note, kn, kn_selnext); - so->so_rcv.sb_flags |= SB_KNOTE; + switch (kn->kn_filter) { + case EVFILT_READ: + if (so->so_options & SO_ACCEPTCONN) + kn->kn_fop = &solisten_filtops; + else + kn->kn_fop = &soread_filtops; + sb = &so->so_rcv; + break; + case EVFILT_WRITE: + kn->kn_fop = &sowrite_filtops; + sb = &so->so_snd; + break; + default: + return (1); + } + + s = splnet(); + SLIST_INSERT_HEAD(&sb->sb_sel.si_note, kn, kn_selnext); + sb->sb_flags |= SB_KNOTE; splx(s); return (0); } @@ -1148,25 +1162,16 @@ filt_soread(struct knote *kn, long hint) kn->kn_data = so->so_rcv.sb_cc; if (so->so_state & SS_CANTRCVMORE) { kn->kn_flags |= EV_EOF; + kn->kn_fflags = so->so_error; return (1); } if (so->so_error) /* temporary udp error */ return (1); + if (kn->kn_sfflags & NOTE_LOWAT) + return (kn->kn_data >= kn->kn_sdata); return (kn->kn_data >= so->so_rcv.sb_lowat); } -int -filt_sowattach(struct knote *kn) -{ - struct socket *so = (struct socket *)kn->kn_fp->f_data; - int s = splnet(); - - SLIST_INSERT_HEAD(&so->so_snd.sb_sel.si_note, kn, kn_selnext); - so->so_snd.sb_flags |= SB_KNOTE; - splx(s); - return (0); -} - void filt_sowdetach(struct knote *kn) { @@ -1188,6 +1193,7 @@ filt_sowrite(struct knote *kn, long hint) kn->kn_data = sbspace(&so->so_snd); if (so->so_state & SS_CANTSENDMORE) { kn->kn_flags |= EV_EOF; + kn->kn_fflags = so->so_error; return (1); } if (so->so_error) /* temporary udp error */ @@ -1195,6 +1201,8 @@ filt_sowrite(struct knote *kn, long hint) if (((so->so_state & SS_ISCONNECTED) == 0) && (so->so_proto->pr_flags & PR_CONNREQUIRED)) return (0); + if (kn->kn_sfflags & NOTE_LOWAT) + return (kn->kn_data >= kn->kn_sdata); return (kn->kn_data >= so->so_snd.sb_lowat); } diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 6bfcf9614ab..9e1b9907a27 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_vnops.c,v 1.27 2000/11/21 21:49:57 provos Exp $ */ +/* $OpenBSD: vfs_vnops.c,v 1.28 2001/03/01 20:54:34 provos Exp $ */ /* $NetBSD: vfs_vnops.c,v 1.20 1996/02/04 02:18:41 christos Exp $ */ /* @@ -61,39 +61,18 @@ #include <uvm/uvm_extern.h> #endif -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> - int vn_read __P((struct file *fp, off_t *off, struct uio *uio, struct ucred *cred)); int vn_write __P((struct file *fp, off_t *off, struct uio *uio, struct ucred *cred)); int vn_select __P((struct file *fp, int which, struct proc *p)); +int vn_kqfilter __P((struct file *fp, struct knote *kn)); int vn_closefile __P((struct file *fp, struct proc *p)); int vn_ioctl __P((struct file *fp, u_long com, caddr_t data, struct proc *p)); struct fileops vnops = - { vn_read, vn_write, vn_ioctl, vn_select, vn_closefile }; - -static int filt_nullattach(struct knote *kn); -static int filt_vnattach(struct knote *kn); -static void filt_vndetach(struct knote *kn); -static int filt_vnode(struct knote *kn, long hint); -static int filt_vnread(struct knote *kn, long hint); - -struct filterops vn_filtops = - { 1, filt_vnattach, filt_vndetach, filt_vnode }; - -/* - * XXX - * filt_vnread is ufs-specific, so the attach routine should really - * switch out to different filterops based on the vn filetype - */ -struct filterops vn_rwfiltops[] = { - { 1, filt_vnattach, filt_vndetach, filt_vnread }, - { 1, filt_nullattach, NULL, NULL }, -}; + { vn_read, vn_write, vn_ioctl, vn_select, vn_kqfilter, vn_closefile }; /* * Common code for vnode open operations. @@ -531,63 +510,9 @@ vn_closefile(fp, p) fp->f_cred, p)); } -static int -filt_vnattach(struct knote *kn) -{ - struct vnode *vp; - - if (kn->kn_fp->f_type != DTYPE_VNODE) - return (EBADF); - - vp = (struct vnode *)kn->kn_fp->f_data; - - /* - * XXX - * this is a hack simply to cause the filter attach to fail - * for non-ufs filesystems, until the support for them is done. - */ - if ((vp)->v_tag != VT_UFS || (vp)->v_type == VFIFO) - return (EOPNOTSUPP); - - simple_lock(&vp->v_selectinfo.vsi_lock); - SLIST_INSERT_HEAD(&vp->v_selectinfo.vsi_selinfo.si_note, kn, kn_selnext); - simple_unlock(&vp->v_selectinfo.vsi_lock); - - return (0); -} - -static void -filt_vndetach(struct knote *kn) -{ - struct vnode *vp = (struct vnode *)kn->kn_fp->f_data; - - simple_lock(&vp->v_selectinfo.vsi_lock); - SLIST_REMOVE(&vp->v_selectinfo.vsi_selinfo.si_note, - kn, knote, kn_selnext); - simple_unlock(&vp->v_selectinfo.vsi_lock); -} - -static int -filt_vnode(struct knote *kn, long hint) -{ - if (kn->kn_sfflags & hint) - kn->kn_fflags |= hint; - return (kn->kn_fflags != 0); -} - -static int -filt_nullattach(struct knote *kn) -{ - return (ENXIO); -} - /*ARGSUSED*/ -static int -filt_vnread(struct knote *kn, long hint) +int +vn_kqfilter(struct file *fp, struct knote *kn) { - struct vnode *vp = (struct vnode *)kn->kn_fp->f_data; - struct inode *ip = VTOI(vp); - - kn->kn_data = ip->i_ffs_size - kn->kn_fp->f_offset; - return (kn->kn_data != 0); + return (VOP_KQFILTER(((struct vnode *)fp->f_data), kn)); } diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src index 722ca9c4fa1..5a98a21d5a6 100644 --- a/sys/kern/vnode_if.src +++ b/sys/kern/vnode_if.src @@ -1,4 +1,4 @@ -# $OpenBSD: vnode_if.src,v 1.9 1998/12/05 16:54:02 csapuntz Exp $ +# $OpenBSD: vnode_if.src,v 1.10 2001/03/01 20:54:34 provos Exp $ # $NetBSD: vnode_if.src,v 1.10 1996/05/11 18:26:27 mycroft Exp $ # # Copyright (c) 1992, 1993 @@ -227,6 +227,14 @@ vop_select { }; # +#% kqfilter vp U U U +# +vop_kqfilter { + IN struct vnode *vp; + IN struct knote *kn; +}; + +# #% revoke vp U U U # vop_revoke { |