diff options
| -rw-r--r-- | sys/kern/init_sysent.c | 4 | ||||
| -rw-r--r-- | sys/kern/kern_descrip.c | 26 | ||||
| -rw-r--r-- | sys/kern/kern_exec.c | 7 | ||||
| -rw-r--r-- | sys/kern/kern_exit.c | 5 | ||||
| -rw-r--r-- | sys/kern/kern_fork.c | 5 | ||||
| -rw-r--r-- | sys/kern/kern_sig.c | 52 | ||||
| -rw-r--r-- | sys/kern/sys_pipe.c | 67 | ||||
| -rw-r--r-- | sys/kern/syscalls.c | 4 | ||||
| -rw-r--r-- | sys/kern/syscalls.master | 5 | ||||
| -rw-r--r-- | sys/kern/uipc_socket.c | 109 | ||||
| -rw-r--r-- | sys/kern/uipc_socket2.c | 2 | ||||
| -rw-r--r-- | sys/kern/uipc_syscalls.c | 4 | ||||
| -rw-r--r-- | sys/kern/vfs_aio.c | 107 | ||||
| -rw-r--r-- | sys/kern/vfs_vnops.c | 78 | ||||
| -rw-r--r-- | sys/miscfs/fifofs/fifo_vnops.c | 86 | ||||
| -rw-r--r-- | sys/sys/aio.h | 7 | ||||
| -rw-r--r-- | sys/sys/file.h | 1 | ||||
| -rw-r--r-- | sys/sys/filedesc.h | 7 | ||||
| -rw-r--r-- | sys/sys/proc.h | 2 | ||||
| -rw-r--r-- | sys/sys/select.h | 3 | ||||
| -rw-r--r-- | sys/sys/socketvar.h | 3 | ||||
| -rw-r--r-- | sys/sys/syscall-hide.h | 4 | ||||
| -rw-r--r-- | sys/sys/syscall.h | 6 | ||||
| -rw-r--r-- | sys/sys/syscall.mk | 6 | ||||
| -rw-r--r-- | sys/sys/sysproto.h | 15 | ||||
| -rw-r--r-- | sys/ufs/ufs/ufs_readwrite.c | 9 | ||||
| -rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 46 |
27 files changed, 623 insertions, 47 deletions
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index b469c91feeda..e1f85f13c998 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.1 2000/05/01 11:15:10 peter Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.74 2000/04/16 18:53:12 jlemon Exp */ #include "opt_compat.h" @@ -382,4 +382,6 @@ struct sysent sysent[] = { { 2, (sy_call_t *)aio_waitcomplete }, /* 359 = aio_waitcomplete */ { 3, (sy_call_t *)getresuid }, /* 360 = getresuid */ { 3, (sy_call_t *)getresgid }, /* 361 = getresgid */ + { 0, (sy_call_t *)kqueue }, /* 362 = kqueue */ + { 6, (sy_call_t *)kevent }, /* 363 = kevent */ }; diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 1de896e9fffe..f0095c97ddac 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -56,6 +56,7 @@ #include <sys/malloc.h> #include <sys/unistd.h> #include <sys/resourcevar.h> +#include <sys/event.h> #include <vm/vm.h> #include <vm/vm_extern.h> @@ -504,6 +505,8 @@ close(p, uap) if (fd < fdp->fd_freefile) fdp->fd_freefile = fd; *pf = 0; + if (fd < fdp->fd_knlistsize) + knote_fdclose(p, fd); return (closef(fp, p)); } @@ -830,9 +833,7 @@ fdinit(p) newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles; newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags; newfdp->fd_fd.fd_nfiles = NDFILE; - - newfdp->fd_fd.fd_freefile = 0; - newfdp->fd_fd.fd_lastfile = 0; + newfdp->fd_fd.fd_knlistsize = -1; return (&newfdp->fd_fd); } @@ -899,6 +900,21 @@ fdcopy(p) newfdp->fd_nfiles = i; bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **)); bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char)); + + /* + * kq descriptors cannot be copied. + */ + if (newfdp->fd_knlistsize != -1) { + fpp = newfdp->fd_ofiles; + for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) + if (*fpp != NULL && (*fpp)->f_type == DTYPE_KQUEUE) + *fpp = NULL; + newfdp->fd_knlist = NULL; + newfdp->fd_knlistsize = -1; + newfdp->fd_knhash = NULL; + newfdp->fd_knhashmask = 0; + } + fpp = newfdp->fd_ofiles; for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) if (*fpp != NULL) @@ -933,6 +949,10 @@ fdfree(p) vrele(fdp->fd_rdir); if (fdp->fd_jdir) vrele(fdp->fd_jdir); + if (fdp->fd_knlist) + FREE(fdp->fd_knlist, M_TEMP); + if (fdp->fd_knhash) + FREE(fdp->fd_knhash, M_TEMP); FREE(fdp, M_FILEDESC); } diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index ba88695e7ee5..c65c8bd48330 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -47,7 +47,6 @@ #include <sys/shm.h> #include <sys/sysctl.h> #include <sys/vnode.h> -#include <sys/buf.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -58,7 +57,6 @@ #include <vm/vm_kern.h> #include <vm/vm_extern.h> #include <vm/vm_object.h> -#include <vm/vm_zone.h> #include <vm/vm_pager.h> #include <machine/reg.h> @@ -311,6 +309,11 @@ interpret: p->p_textvp = ndp->ni_vp; /* + * notify others that we exec'd + */ + KNOTE(&p->p_klist, NOTE_EXEC); + + /* * If tracing the process, trap to debugger so breakpoints * can be set before the program executes. */ diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 9c2005c926cd..9115f9775a36 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -307,6 +307,11 @@ exit1(p, rv) switchticks = ticks; /* + * notify interested parties of our demise. + */ + KNOTE(&p->p_klist, NOTE_EXIT); + + /* * Notify parent that we're gone. If parent has the PS_NOCLDWAIT * flag set, notify process 1 instead (and hope it will handle * this situation). diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index fc69d282ec2e..62296b27d60e 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -509,6 +509,11 @@ again: PRELE(p1); /* + * tell any interested parties about the new process + */ + KNOTE(&p1->p_klist, NOTE_FORK | p2->p_pid); + + /* * Preserve synchronization semantics of vfork. If waiting for * child to exec or exit, set P_PPWAIT on child, and sleep on our * proc (in case of exit). diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index c3bb68f73753..880ecc753299 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -49,6 +49,7 @@ #include <sys/resourcevar.h> #include <sys/namei.h> #include <sys/vnode.h> +#include <sys/event.h> #include <sys/proc.h> #include <sys/pioctl.h> #include <sys/systm.h> @@ -62,7 +63,6 @@ #include <sys/sysctl.h> #include <sys/malloc.h> -#include <vm/vm_zone.h> #include <machine/cpu.h> #ifdef SMP @@ -82,6 +82,13 @@ static int sig_ffs __P((sigset_t *set)); static int sigprop __P((int sig)); static void stop __P((struct proc *)); +static int filt_sigattach(struct knote *kn); +static void filt_sigdetach(struct knote *kn); +static int filt_signal(struct knote *kn, long hint); + +struct filterops sig_filtops = + { 0, filt_sigattach, filt_sigdetach, filt_signal }; + static int kern_logsigexit = 1; SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, &kern_logsigexit, 0, @@ -996,6 +1003,8 @@ psignal(p, sig) panic("psignal signal number"); } + KNOTE(&p->p_klist, NOTE_SIGNAL | sig); + prop = sigprop(sig); /* @@ -1682,3 +1691,44 @@ pgsigio(sigio, sig, checkctty) psignal(p, sig); } } + +static int +filt_sigattach(struct knote *kn) +{ + struct proc *p = curproc; + + kn->kn_ptr.p_proc = p; + kn->kn_flags |= EV_CLEAR; /* automatically set */ + + /* XXX lock the proc here while adding to the list? */ + SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext); + + return (0); +} + +static void +filt_sigdetach(struct knote *kn) +{ + struct proc *p = kn->kn_ptr.p_proc; + + SLIST_REMOVE(&p->p_klist, kn, knote, kn_selnext); +} + +/* + * signal knotes are shared with proc knotes, so we apply a mask to + * the hint in order to differentiate them from process hints. This + * could be avoided by using a signal-specific knote list, but probably + * isn't worth the trouble. + */ +static int +filt_signal(struct knote *kn, long hint) +{ + + if (hint & NOTE_SIGNAL) { + hint &= ~NOTE_SIGNAL; + + if (kn->kn_id == hint) + kn->kn_data++; + } + return (kn->kn_data != 0); +} diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index a181b5a70e49..be868830f2d0 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -65,6 +65,7 @@ #include <sys/pipe.h> #include <sys/vnode.h> #include <sys/uio.h> +#include <sys/event.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -100,6 +101,16 @@ static int pipe_ioctl __P((struct file *fp, u_long cmd, caddr_t data, struct pro static struct fileops pipeops = { pipe_read, pipe_write, pipe_ioctl, pipe_poll, pipe_stat, pipe_close }; +static int filt_pipeattach(struct knote *kn); +static void filt_pipedetach(struct knote *kn); +static int filt_piperead(struct knote *kn, long hint); +static 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 }, +}; + /* * 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 @@ -316,6 +327,7 @@ pipeselwakeup(cpipe) } if ((cpipe->pipe_state & PIPE_ASYNC) && cpipe->pipe_sigio) pgsigio(cpipe->pipe_sigio, SIGIO, 0); + KNOTE(&cpipe->pipe_sel.si_note, 0); } /* ARGSUSED */ @@ -1159,3 +1171,58 @@ pipeclose(cpipe) zfree(pipe_zone, cpipe); } } + +static int +filt_pipeattach(struct knote *kn) +{ + struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; + + SLIST_INSERT_HEAD(&rpipe->pipe_sel.si_note, kn, kn_selnext); + return (0); +} + +static void +filt_pipedetach(struct knote *kn) +{ + struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; + + SLIST_REMOVE(&rpipe->pipe_sel.si_note, kn, knote, kn_selnext); +} + +/*ARGSUSED*/ +static int +filt_piperead(struct knote *kn, long hint) +{ + struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; + struct pipe *wpipe = rpipe->pipe_peer; + + kn->kn_data = rpipe->pipe_buffer.cnt; + if ((kn->kn_data == 0) && (rpipe->pipe_state & PIPE_DIRECTW)) + kn->kn_data = rpipe->pipe_map.cnt; + + if ((rpipe->pipe_state & PIPE_EOF) || + (wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) { + kn->kn_flags |= EV_EOF; + return (1); + } + return (kn->kn_data > 0); +} + +/*ARGSUSED*/ +static int +filt_pipewrite(struct knote *kn, long hint) +{ + struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; + struct pipe *wpipe = rpipe->pipe_peer; + + if ((wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) { + kn->kn_data = 0; + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_data = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt; + if ((wpipe->pipe_state & PIPE_DIRECTW) == 0) + kn->kn_data = 0; + + return (kn->kn_data >= PIPE_BUF); +} diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index b3f5facf7607..70013a30040a 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.1 2000/05/01 11:15:10 peter Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.74 2000/04/16 18:53:12 jlemon Exp */ char *syscallnames[] = { @@ -369,4 +369,6 @@ char *syscallnames[] = { "aio_waitcomplete", /* 359 = aio_waitcomplete */ "getresuid", /* 360 = getresuid */ "getresgid", /* 361 = getresgid */ + "kqueue", /* 362 = kqueue */ + "kevent", /* 363 = kevent */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 6e6ce514d4e6..5a62eb2a5aaa 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -513,3 +513,8 @@ 359 STD BSD { int aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); } 360 STD BSD { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } 361 STD BSD { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } +362 STD BSD { int kqueue(void); } +363 STD BSD { int kevent(int fd, \ + int nchanges, struct kevent **changelist, \ + int nevents, struct kevent *eventlist, \ + struct timespec *timeout); } diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index e4433be4a602..76495e19244f 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -40,8 +40,10 @@ #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/domain.h> +#include <sys/file.h> /* for struct knote */ #include <sys/kernel.h> #include <sys/malloc.h> +#include <sys/event.h> #include <sys/poll.h> #include <sys/proc.h> #include <sys/protosw.h> @@ -55,6 +57,22 @@ #include <machine/limits.h> +static int filt_sorattach(struct knote *kn); +static void filt_sordetach(struct knote *kn); +static int filt_soread(struct knote *kn, long hint); +static int filt_sowattach(struct knote *kn); +static void filt_sowdetach(struct knote *kn); +static int filt_sowrite(struct knote *kn, long hint); +static int filt_solisten(struct knote *kn, long hint); + +static struct filterops solisten_filtops = + { 1, filt_sorattach, filt_sordetach, filt_solisten }; + +struct filterops so_rwfiltops[] = { + { 1, filt_sorattach, filt_sordetach, filt_soread }, + { 1, filt_sowattach, filt_sowdetach, filt_sowrite }, +}; + struct vm_zone *socket_zone; so_gen_t so_gencnt; /* generation count for sockets */ @@ -1388,3 +1406,94 @@ sopoll(struct socket *so, int events, struct ucred *cred, struct proc *p) splx(s); return (revents); } + +static int +filt_sorattach(struct knote *kn) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + int s = splnet(); + + 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; + splx(s); + return (0); +} + +static void +filt_sordetach(struct knote *kn) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + int s = splnet(); + + SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) + so->so_rcv.sb_flags &= ~SB_KNOTE; + splx(s); +} + +/*ARGSUSED*/ +static int +filt_soread(struct knote *kn, long hint) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + + kn->kn_data = so->so_rcv.sb_cc; + if (so->so_state & SS_CANTRCVMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + return (kn->kn_data > 0); +} + +static 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); +} + +static void +filt_sowdetach(struct knote *kn) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + int s = splnet(); + + SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) + so->so_snd.sb_flags &= ~SB_KNOTE; + splx(s); +} + +/*ARGSUSED*/ +static int +filt_sowrite(struct knote *kn, long hint) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + + kn->kn_data = sbspace(&so->so_snd); + if (so->so_state & SS_CANTSENDMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + if (((so->so_state & SS_ISCONNECTED) == 0) && + (so->so_proto->pr_flags & PR_CONNREQUIRED)) + return (0); + return (kn->kn_data >= so->so_snd.sb_lowat); +} + +/*ARGSUSED*/ +static int +filt_solisten(struct knote *kn, long hint) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + + kn->kn_data = so->so_qlen - so->so_incqlen; + return (! TAILQ_EMPTY(&so->so_comp)); +} diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 93d1fdacec5a..6184c233782e 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -51,6 +51,7 @@ #include <sys/signalvar.h> #include <sys/sysctl.h> #include <sys/aio.h> /* for aio_swake proto */ +#include <sys/event.h> int maxsockets; @@ -340,6 +341,7 @@ sowakeup(so, sb) (*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT); if (sb->sb_flags & SB_AIO) aio_swake(so, sb); + KNOTE(&sb->sb_sel.si_note, 0); } /* diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 268125f94773..298bbe12b386 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -46,6 +46,7 @@ #include <sys/sysproto.h> #include <sys/malloc.h> #include <sys/filedesc.h> +#include <sys/event.h> #include <sys/proc.h> #include <sys/fcntl.h> #include <sys/file.h> @@ -256,6 +257,9 @@ accept1(p, uap, compat) } else p->p_retval[0] = fd; + /* connection has been removed from the listen queue */ + KNOTE(&head->so_rcv.sb_sel.si_note, 0); + so->so_state &= ~SS_COMP; so->so_head = NULL; if (head->so_sigio != NULL) diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 9ef54a7a6d13..6c5bab565ee3 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -38,6 +38,7 @@ #include <sys/sysctl.h> #include <sys/vnode.h> #include <sys/conf.h> +#include <sys/event.h> #include <vm/vm.h> #include <vm/vm_extern.h> @@ -210,6 +211,13 @@ static int aio_fphysio(struct proc *p, struct aiocblist *aiocbe, int type); static int aio_qphysio(struct proc *p, struct aiocblist *iocb); static void aio_daemon(void *uproc); +static int filt_aioattach(struct knote *kn); +static void filt_aiodetach(struct knote *kn); +static int filt_aio(struct knote *kn, long hint); + +struct filterops aio_filtops = + { 0, filt_aioattach, filt_aiodetach, filt_aio }; + SYSINIT(aio, SI_SUB_VFS, SI_ORDER_ANY, aio_onceonly, NULL); static vm_zone_t kaio_zone = 0, aiop_zone = 0, aiocb_zone = 0, aiol_zone = 0; @@ -328,6 +336,9 @@ aio_free_entry(struct aiocblist *aiocbe) num_buf_aio--; } + /* aiocbe is going away, we need to destroy any knotes */ + knote_remove(p, &aiocbe->klist); + if ((ki->kaio_flags & KAIO_WAKEUP) || ((ki->kaio_flags & KAIO_RUNDOWN) && ((ki->kaio_buffer_count == 0) && (ki->kaio_queue_count == 0)))) { ki->kaio_flags &= ~KAIO_WAKEUP; @@ -806,6 +817,7 @@ aio_daemon(void *uproc) plist); } splx(s); + KNOTE(&aiocbe->klist, 0); if (aiocbe->jobflags & AIOCBLIST_RUNDOWN) { wakeup(aiocbe); @@ -933,7 +945,7 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) struct aio_liojob *lj; int fd; int s; - int cnt; + int cnt, notify; cb = &aiocbe->uaiocb; fdp = p->p_fd; @@ -1034,6 +1046,7 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) /* Perform transfer. */ BUF_STRATEGY(bp, 0); + notify = 0; s = splbio(); /* @@ -1059,9 +1072,12 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) TAILQ_REMOVE(&aio_bufjobs, aiocbe, list); TAILQ_REMOVE(&ki->kaio_bufqueue, aiocbe, plist); TAILQ_INSERT_TAIL(&ki->kaio_bufdone, aiocbe, plist); + notify = 1; } } splx(s); + if (notify) + KNOTE(&aiocbe->klist, 0); return 0; doerror: @@ -1174,7 +1190,7 @@ _aio_aqueue(struct proc *p, struct aiocb *job, struct aio_liojob *lj, int type) unsigned int fd; struct socket *so; int s; - int error; + int error = 0; int opcode; struct aiocblist *aiocbe; struct aioproclist *aiop; @@ -1187,6 +1203,7 @@ _aio_aqueue(struct proc *p, struct aiocb *job, struct aio_liojob *lj, int type) aiocbe->inputcharge = 0; aiocbe->outputcharge = 0; + SLIST_INIT(&aiocbe->klist); suword(&job->_aiocb_private.status, -1); suword(&job->_aiocb_private.error, 0); @@ -1272,6 +1289,45 @@ _aio_aqueue(struct proc *p, struct aiocb *job, struct aio_liojob *lj, int type) return EINVAL; } + /* + * XXX + * Figure out how to do this properly. This currently won't + * work on the alpha, since we're passing in a pointer via + * aio_lio_opcode, which is an int. + */ + { + struct kevent kev, *kevp; + struct kqueue *kq; + + kevp = (struct kevent *)job->aio_lio_opcode; + if (kevp == NULL) + goto no_kqueue; + + error = copyin((caddr_t)kevp, (caddr_t)&kev, sizeof(kev)); + if (error) + goto aqueue_fail; + + if ((u_int)kev.ident >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[kev.ident]) == NULL || + (fp->f_type != DTYPE_KQUEUE)) { + error = EBADF; + goto aqueue_fail; + } + kq = (struct kqueue *)fp->f_data; + kev.ident = (u_long)aiocbe; + kev.filter = EVFILT_AIO; + kev.flags = EV_ADD | EV_ENABLE | EV_FLAG1; + error = kqueue_register(kq, &kev, p); +aqueue_fail: + if (error) { + TAILQ_INSERT_HEAD(&aio_freejobs, aiocbe, list); + if (type == 0) + suword(&job->_aiocb_private.error, error); + return (error); + } +no_kqueue: + } + suword(&job->_aiocb_private.error, EINPROGRESS); aiocbe->uaiocb._aiocb_private.error = EINPROGRESS; aiocbe->userproc = p; @@ -1629,6 +1685,7 @@ aio_cancel(struct proc *p, struct aio_cancel_args *uap) cbe->uaiocb._aiocb_private.status=-1; cbe->uaiocb._aiocb_private.error=ECANCELED; cancelled++; +/* XXX cancelled, knote? */ if (cbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL) psignal(cbe->userproc, cbe->uaiocb.aio_sigevent.sigev_signo); @@ -1667,6 +1724,7 @@ aio_cancel(struct proc *p, struct aio_cancel_args *uap) cbe->jobstate = JOBST_JOBFINISHED; cbe->uaiocb._aiocb_private.status = -1; cbe->uaiocb._aiocb_private.error = ECANCELED; +/* XXX cancelled, knote? */ if (cbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL) psignal(cbe->userproc, cbe->uaiocb.aio_sigevent.sigev_signo); @@ -2174,7 +2232,8 @@ aio_physwakeup(struct buf *bp) TAILQ_REMOVE(&aio_bufjobs, aiocbe, list); TAILQ_REMOVE(&ki->kaio_bufqueue, aiocbe, plist); TAILQ_INSERT_TAIL(&ki->kaio_bufdone, aiocbe, plist); - + + KNOTE(&aiocbe->klist, 0); /* Do the wakeup. */ if (ki->kaio_flags & (KAIO_RUNDOWN|KAIO_WAKEUP)) { ki->kaio_flags &= ~KAIO_WAKEUP; @@ -2267,3 +2326,45 @@ aio_waitcomplete(struct proc *p, struct aio_waitcomplete_args *uap) } #endif /* VFS_AIO */ } + +static int +filt_aioattach(struct knote *kn) +{ + struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_id; + + /* + * The aiocbe pointer must be validated before using it, so + * registration is restricted to the kernel; the user cannot + * set EV_FLAG1. + */ + if ((kn->kn_flags & EV_FLAG1) == 0) + return (EPERM); + kn->kn_flags &= ~EV_FLAG1; + + SLIST_INSERT_HEAD(&aiocbe->klist, kn, kn_selnext); + + return (0); +} + +static void +filt_aiodetach(struct knote *kn) +{ + struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_id; + int s = splhigh(); /* XXX no clue, so overkill */ + + SLIST_REMOVE(&aiocbe->klist, kn, knote, kn_selnext); + splx(s); +} + +/*ARGSUSED*/ +static int +filt_aio(struct knote *kn, long hint) +{ + struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_id; + + kn->kn_data = 0; /* XXX data returned? */ + if (aiocbe->jobstate != JOBST_JOBFINISHED) + return (0); + kn->kn_flags |= EV_EOF; + return (1); +} diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 1b4a5e07f73c..0f9713854b5f 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -52,7 +52,9 @@ #include <sys/filio.h> #include <sys/ttycom.h> #include <sys/conf.h> -#include <vm/vm_zone.h> + +#include <ufs/ufs/quota.h> +#include <ufs/ufs/inode.h> static int vn_closefile __P((struct file *fp, struct proc *p)); static int vn_ioctl __P((struct file *fp, u_long com, caddr_t data, @@ -68,6 +70,25 @@ static int vn_write __P((struct file *fp, struct uio *uio, struct fileops vnops = { vn_read, vn_write, vn_ioctl, vn_poll, vn_statfile, 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 }, +}; + /* * Common code for vnode open operations. * Check permissions, and call the VOP_OPEN or VOP_CREATE routine. @@ -639,3 +660,58 @@ vn_closefile(fp, p) return (vn_close(((struct vnode *)fp->f_data), fp->f_flag, fp->f_cred, p)); } + +static int +filt_vnattach(struct knote *kn) +{ + struct vnode *vp; + + if (kn->kn_fp->f_type != DTYPE_VNODE && + kn->kn_fp->f_type != DTYPE_FIFO) + return (EBADF); + + vp = (struct vnode *)kn->kn_fp->f_data; + + simple_lock(&vp->v_pollinfo.vpi_lock); + SLIST_INSERT_HEAD(&vp->v_pollinfo.vpi_selinfo.si_note, kn, kn_selnext); + simple_unlock(&vp->v_pollinfo.vpi_lock); + + return (0); +} + +static void +filt_vndetach(struct knote *kn) +{ + struct vnode *vp = (struct vnode *)kn->kn_fp->f_data; + + simple_lock(&vp->v_pollinfo.vpi_lock); + SLIST_REMOVE(&vp->v_pollinfo.vpi_selinfo.si_note, + kn, knote, kn_selnext); + simple_unlock(&vp->v_pollinfo.vpi_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) +{ + struct vnode *vp = (struct vnode *)kn->kn_fp->f_data; + struct inode *ip = VTOI(vp); + + kn->kn_data = ip->i_size - kn->kn_fp->f_offset; + return (kn->kn_data != 0); +} diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c index b64f957b4960..5bd13a771d48 100644 --- a/sys/miscfs/fifofs/fifo_vnops.c +++ b/sys/miscfs/fifofs/fifo_vnops.c @@ -46,6 +46,7 @@ #include <sys/filio.h> #include <sys/fcntl.h> #include <sys/file.h> +#include <sys/event.h> #include <sys/poll.h> #include <sys/un.h> #include <miscfs/fifofs/fifo.h> @@ -75,6 +76,17 @@ 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 }, +}; vop_t **fifo_vnodeop_p; static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = { @@ -343,6 +355,80 @@ fifo_ioctl(ap) return (0); } +static int +filt_fiforattach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + 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; + + SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) + so->so_rcv.sb_flags &= ~SB_KNOTE; +} + +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; + + kn->kn_data = so->so_rcv.sb_cc; + if (so->so_state & SS_CANTRCVMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_flags &= ~EV_EOF; + 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; + + SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) + so->so_snd.sb_flags &= ~SB_KNOTE; +} + +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; + + kn->kn_data = sbspace(&so->so_snd); + if (so->so_state & SS_CANTSENDMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_flags &= ~EV_EOF; + return (kn->kn_data >= so->so_snd.sb_lowat); +} + /* ARGSUSED */ static int fifo_poll(ap) diff --git a/sys/sys/aio.h b/sys/sys/aio.h index e905c899e14f..946ac0bec4c8 100644 --- a/sys/sys/aio.h +++ b/sys/sys/aio.h @@ -22,7 +22,6 @@ #include <sys/time.h> #include <sys/types.h> #include <sys/signal.h> -#include <sys/socketvar.h> /* * Returned by aio_cancel: @@ -168,11 +167,15 @@ struct aiocblist { struct aioproclist *jobaioproc;/* AIO process descriptor */ struct aio_liojob *lio; /* Optional lio job */ struct aiocb *uuaiocb; /* Pointer in userspace of aiocb */ + struct klist klist; /* list of knotes */ struct aiocb uaiocb; /* Kernel I/O control block */ }; -void aio_proc_rundown(struct proc *p); +/* Forward declarations for prototypes below. */ +struct socket; +struct sockbuf; +void aio_proc_rundown(struct proc *p); void aio_swake(struct socket *, struct sockbuf *); #endif diff --git a/sys/sys/file.h b/sys/sys/file.h index 798642500ce7..7ad7a8158b4f 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -60,6 +60,7 @@ struct file { #define DTYPE_SOCKET 2 /* communications endpoint */ #define DTYPE_PIPE 3 /* pipe */ #define DTYPE_FIFO 4 /* fifo (named pipe) */ +#define DTYPE_KQUEUE 5 /* event queue */ short f_type; /* descriptor type */ short f_count; /* reference count */ short f_msgcount; /* references from message queue */ diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 43630baa9452..9b07cfeddba2 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -56,6 +56,8 @@ #define NDFILE 20 #define NDEXTENT 50 /* 250 bytes in 256-byte alloc. */ +struct klist; + struct filedesc { struct file **fd_ofiles; /* file structures for open files */ char *fd_ofileflags; /* per-process open file flags */ @@ -67,6 +69,11 @@ struct filedesc { u_short fd_freefile; /* approx. next free file */ u_short fd_cmask; /* mask for file creation */ u_short fd_refcnt; /* reference count */ + + int fd_knlistsize; /* size of knlist */ + struct klist *fd_knlist; /* list of attached knotes */ + u_long fd_knhashmask; /* size of knhash */ + struct klist *fd_knhash; /* hash table for attached knotes */ }; /* diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 4c2eead9f775..65b47f287e19 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -52,6 +52,7 @@ #include <sys/time.h> /* For structs itimerval, timeval. */ #endif #include <sys/ucred.h> +#include <sys/event.h> /* For struct klist */ /* * One structure allocated per session. @@ -205,6 +206,7 @@ struct proc { sigset_t p_oldsigmask; /* saved mask from before sigpause */ int p_sig; /* for core dump/debugger XXX */ u_long p_code; /* for core dump/debugger XXX */ + struct klist p_klist; /* knotes attached to this process */ /* End area that is zeroed on creation. */ #define p_endzero p_startcopy diff --git a/sys/sys/select.h b/sys/sys/select.h index 8f58d858ba07..4909a341f5b0 100644 --- a/sys/sys/select.h +++ b/sys/sys/select.h @@ -37,12 +37,15 @@ #ifndef _SYS_SELECT_H_ #define _SYS_SELECT_H_ +#include <sys/event.h> /* for struct klist */ + /* * Used to maintain information about processes that wish to be * notified when I/O becomes possible. */ struct selinfo { pid_t si_pid; /* process to be notified */ + struct klist si_note; /* kernel note list */ short si_flags; /* see below */ }; #define SI_COLL 0x0001 /* collision occurred */ diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 1b6d94ce348c..add6eb6c988e 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -104,6 +104,7 @@ struct socket { #define SB_UPCALL 0x20 /* someone wants an upcall */ #define SB_NOINTR 0x40 /* operations not interruptible */ #define SB_AIO 0x80 /* AIO operations queued */ +#define SB_KNOTE 0x100 /* kernel note attached */ void (*so_upcall) __P((struct socket *, void *, int)); void *so_upcallarg; @@ -172,7 +173,7 @@ struct xsocket { * Do we need to notify the other side when I/O is possible? */ #define sb_notify(sb) (((sb)->sb_flags & (SB_WAIT | SB_SEL | SB_ASYNC | \ - SB_UPCALL | SB_AIO)) != 0) + SB_UPCALL | SB_AIO | SB_KNOTE)) != 0) /* * How much space is there in a socket buffer (so->so_snd or so->so_rcv)? diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h index 8e7f99990385..1612418fd382 100644 --- a/sys/sys/syscall-hide.h +++ b/sys/sys/syscall-hide.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.1 2000/05/01 11:15:10 peter Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.74 2000/04/16 18:53:12 jlemon Exp */ HIDE_POSIX(fork) @@ -278,3 +278,5 @@ HIDE_BSD(extattr_delete_file) HIDE_BSD(aio_waitcomplete) HIDE_BSD(getresuid) HIDE_BSD(getresgid) +HIDE_BSD(kqueue) +HIDE_BSD(kevent) diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 6149f4c5dba6..d5359581e048 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.1 2000/05/01 11:15:10 peter Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.74 2000/04/16 18:53:12 jlemon Exp */ #define SYS_syscall 0 @@ -283,4 +283,6 @@ #define SYS_aio_waitcomplete 359 #define SYS_getresuid 360 #define SYS_getresgid 361 -#define SYS_MAXSYSCALL 362 +#define SYS_kqueue 362 +#define SYS_kevent 363 +#define SYS_MAXSYSCALL 364 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index d9a0371d6bcb..6924a70dd271 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # FreeBSD system call names. # DO NOT EDIT-- this file is automatically generated. # $FreeBSD$ -# created from FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.1 2000/05/01 11:15:10 peter Exp +# created from FreeBSD: src/sys/kern/syscalls.master,v 1.74 2000/04/16 18:53:12 jlemon Exp MIASM = \ syscall.o \ exit.o \ @@ -233,4 +233,6 @@ MIASM = \ extattr_delete_file.o \ aio_waitcomplete.o \ getresuid.o \ - getresgid.o + getresgid.o \ + kqueue.o \ + kevent.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index dbbd4911fd97..50ef14149220 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.1 2000/05/01 11:15:10 peter Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.74 2000/04/16 18:53:12 jlemon Exp */ #ifndef _SYS_SYSPROTO_H_ @@ -1010,6 +1010,17 @@ struct getresgid_args { gid_t * egid; char egid_[PAD_(gid_t *)]; gid_t * sgid; char sgid_[PAD_(gid_t *)]; }; +struct kqueue_args { + register_t dummy; +}; +struct kevent_args { + int fd; char fd_[PAD_(int)]; + int nchanges; char nchanges_[PAD_(int)]; + struct kevent ** changelist; char changelist_[PAD_(struct kevent **)]; + int nevents; char nevents_[PAD_(int)]; + struct kevent * eventlist; char eventlist_[PAD_(struct kevent *)]; + struct timespec * timeout; char timeout_[PAD_(struct timespec *)]; +}; int nosys __P((struct proc *, struct nosys_args *)); void exit __P((struct proc *, struct rexit_args *)) __dead2; int fork __P((struct proc *, struct fork_args *)); @@ -1239,6 +1250,8 @@ int extattr_delete_file __P((struct proc *, struct extattr_delete_file_args *)); int aio_waitcomplete __P((struct proc *, struct aio_waitcomplete_args *)); int getresuid __P((struct proc *, struct getresuid_args *)); int getresgid __P((struct proc *, struct getresgid_args *)); +int kqueue __P((struct proc *, struct kqueue_args *)); +int kevent __P((struct proc *, struct kevent_args *)); #ifdef COMPAT_43 diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c index 48088e9da7a1..df295f7faa82 100644 --- a/sys/ufs/ufs/ufs_readwrite.c +++ b/sys/ufs/ufs/ufs_readwrite.c @@ -47,7 +47,10 @@ #include <vm/vm_pager.h> #include <vm/vm_map.h> #include <vm/vnode_pager.h> -#include <sys/poll.h> +#include <sys/event.h> + +#define VN_KNOTE(vp, b) \ + KNOTE((struct klist *)&vp->v_pollinfo.vpi_selinfo.si_note, (b)) /* * Vnode op for reading. @@ -513,6 +516,8 @@ WRITE(ap) */ if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0) ip->i_mode &= ~(ISUID | ISGID); + if (resid > uio->uio_resid) + VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); if (error) { if (ioflag & IO_UNIT) { (void)UFS_TRUNCATE(vp, osize, @@ -522,8 +527,6 @@ WRITE(ap) } } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) error = UFS_UPDATE(vp, 1); - if (!error) - VN_POLLEVENT(vp, POLLWRITE | (extended ? POLLEXTEND : 0)); if (object) vm_object_vndeallocate(object); diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index c3f60181b076..72c2a4ed664a 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -56,10 +56,9 @@ #include <sys/malloc.h> #include <sys/dirent.h> #include <sys/lockf.h> -#include <sys/poll.h> +#include <sys/event.h> #include <sys/conf.h> -#include <vm/vm_zone.h> #include <vm/vm.h> #include <vm/vm_extern.h> @@ -119,6 +118,8 @@ union _qcvt { tmp.val[_QUAD_LOWWORD] = (l); \ (q) = tmp.qcvt; \ } +#define VN_KNOTE(vp, b) \ + KNOTE(&vp->v_pollinfo.vpi_selinfo.si_note, (b)) /* * A virgin directory (no blushing please). @@ -185,7 +186,7 @@ ufs_create(ap) ap->a_dvp, ap->a_vpp, ap->a_cnp); if (error) return (error); - VN_POLLEVENT(ap->a_dvp, POLLWRITE); + VN_KNOTE(ap->a_dvp, NOTE_WRITE); return (0); } @@ -211,7 +212,7 @@ ufs_mknod(ap) ap->a_dvp, vpp, ap->a_cnp); if (error) return (error); - VN_POLLEVENT(ap->a_dvp, POLLWRITE); + VN_KNOTE(ap->a_dvp, NOTE_WRITE); ip = VTOI(*vpp); ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; if (vap->va_rdev != VNOVAL) { @@ -527,7 +528,7 @@ ufs_setattr(ap) return (EROFS); error = ufs_chmod(vp, (int)vap->va_mode, cred, p); } - VN_POLLEVENT(vp, POLLATTRIB); + VN_KNOTE(vp, NOTE_ATTRIB); return (error); } @@ -705,8 +706,8 @@ ufs_remove(ap) goto out; } error = ufs_dirremove(dvp, ip, ap->a_cnp->cn_flags, 0); - VN_POLLEVENT(vp, POLLNLINK); - VN_POLLEVENT(dvp, POLLWRITE); + VN_KNOTE(vp, NOTE_DELETE); + VN_KNOTE(dvp, NOTE_WRITE); out: return (error); } @@ -772,8 +773,8 @@ out1: if (tdvp != vp) VOP_UNLOCK(vp, 0, p); out2: - VN_POLLEVENT(vp, POLLNLINK); - VN_POLLEVENT(tdvp, POLLWRITE); + VN_KNOTE(vp, NOTE_LINK); + VN_KNOTE(tdvp, NOTE_WRITE); return (error); } @@ -994,7 +995,7 @@ abortit: oldparent = dp->i_number; doingdirectory = 1; } - VN_POLLEVENT(fdvp, POLLWRITE); + VN_KNOTE(fdvp, NOTE_WRITE); /* XXX right place? */ vrele(fdvp); /* @@ -1100,7 +1101,7 @@ abortit: } goto bad; } - VN_POLLEVENT(tdvp, POLLWRITE); + VN_KNOTE(tdvp, NOTE_WRITE); vput(tdvp); } else { if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) @@ -1157,7 +1158,6 @@ abortit: if (DOINGSOFTDEP(tvp)) softdep_change_linkcnt(xp); } - VN_POLLEVENT(tdvp, POLLWRITE); if (doingdirectory && !DOINGSOFTDEP(tvp)) { /* * Truncate inode. The only stuff left in the directory @@ -1181,8 +1181,9 @@ abortit: tcnp->cn_cred, tcnp->cn_proc)) != 0) goto bad; } + VN_KNOTE(tdvp, NOTE_WRITE); vput(tdvp); - VN_POLLEVENT(tvp, POLLNLINK); /* XXX this right? */ + VN_KNOTE(tvp, NOTE_DELETE); vput(tvp); xp = NULL; } @@ -1237,6 +1238,7 @@ abortit: error = ufs_dirremove(fdvp, xp, fcnp->cn_flags, 0); xp->i_flag &= ~IN_RENAME; } + VN_KNOTE(fvp, NOTE_RENAME); if (dp) vput(fdvp); if (xp) @@ -1313,10 +1315,10 @@ ufs_mkdir(ap) #ifdef QUOTA struct ucred ucred, *ucp; ucp = cnp->cn_cred; -#endif I +#endif /* * If we are hacking owners here, (only do this where told to) - * and we are not giving it TOO root, (would subvert quotas) + * and we are not giving it TO root, (would subvert quotas) * then go ahead and give it to the other user. * The new directory also inherits the SUID bit. * If user's UID and dir UID are the same, @@ -1425,7 +1427,6 @@ ufs_mkdir(ap) (void)VOP_BWRITE(bp->b_vp, bp); goto bad; } - VN_POLLEVENT(dvp, POLLWRITE); /* XXX right place? */ /* * Directory set up, now install its entry in the parent directory. * @@ -1446,6 +1447,7 @@ ufs_mkdir(ap) bad: if (error == 0) { + VN_KNOTE(dvp, NOTE_WRITE); *ap->a_vpp = tvp; } else { dp->i_effnlink--; @@ -1536,7 +1538,7 @@ ufs_rmdir(ap) } goto out; } - VN_POLLEVENT(dvp, POLLWRITE|POLLNLINK); + VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); cache_purge(dvp); /* * Truncate inode. The only stuff left in the directory is "." and @@ -1556,7 +1558,7 @@ ufs_rmdir(ap) } cache_purge(vp); out: - VN_POLLEVENT(vp, POLLNLINK); + VN_KNOTE(vp, NOTE_DELETE); return (error); } @@ -1581,7 +1583,7 @@ ufs_symlink(ap) vpp, ap->a_cnp); if (error) return (error); - VN_POLLEVENT(ap->a_dvp, POLLWRITE); + VN_KNOTE(ap->a_dvp, NOTE_WRITE); vp = *vpp; len = strlen(ap->a_target); if (len < vp->v_mount->mnt_maxsymlinklen) { @@ -2085,11 +2087,11 @@ ufs_makeinode(mode, dvp, vpp, cnp) #ifdef QUOTA struct ucred ucred, *ucp; ucp = cnp->cn_cred; -#endif I +#endif /* * If we are not the owner of the directory, * and we are hacking owners here, (only do this where told to) - * and we are not giving it TOO root, (would subvert quotas) + * and we are not giving it TO root, (would subvert quotas) * then go ahead and give it to the other user. * Note that this drops off the execute bits for security. */ @@ -2300,5 +2302,3 @@ ufs_vnoperatespec(ap) { return (VOCALL(ufs_specop_p, ap->a_desc->vdesc_offset, ap)); } - - |
