diff options
author | jlemon <jlemon@FreeBSD.org> | 2000-04-16 18:53:38 +0000 |
---|---|---|
committer | jlemon <jlemon@FreeBSD.org> | 2000-04-16 18:53:38 +0000 |
commit | c41c876463ee8c302f06554537e0fb22a3fcdca4 (patch) | |
tree | d2f87a6af04c4f35f243bf580d099496a4131330 /sys/kern/vfs_vnops.c | |
parent | f8f9ad64d408b963d98d0e11b37e871763557e95 (diff) | |
download | FreeBSD-src-c41c876463ee8c302f06554537e0fb22a3fcdca4.zip FreeBSD-src-c41c876463ee8c302f06554537e0fb22a3fcdca4.tar.gz |
Introduce kqueue() and kevent(), a kernel event notification facility.
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r-- | sys/kern/vfs_vnops.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 9f1a387..705ac34 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -54,6 +54,9 @@ #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, struct proc *p)); @@ -68,6 +71,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. @@ -637,3 +659,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); +} |