diff options
author | Niels Provos <provos@cvs.openbsd.org> | 2000-11-21 21:49:58 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 2000-11-21 21:49:58 +0000 |
commit | 94de05185b93d013f30d8874f4fea920b09ed369 (patch) | |
tree | b6263191caa04e1a1a335966375a2a0e1efe3ba3 /sys/kern | |
parent | a12c4c01eea21cd09905b7d403f30c7060520a3b (diff) |
support for kernel events on vnodes, from jlemon@freebsd.org, okay art@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_event.c | 10 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 85 |
2 files changed, 89 insertions, 6 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 4c5fed5e9ac..d407ba8ad27 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_event.c,v 1.5 2000/11/18 22:16:49 provos Exp $ */ +/* $OpenBSD: kern_event.c,v 1.6 2000/11/21 21:49:57 provos Exp $ */ /*- * Copyright (c) 1999,2000 Jonathan Lemon <jlemon@FreeBSD.org> @@ -100,8 +100,8 @@ extern struct filterops so_rwfiltops[]; extern struct filterops pipe_rwfiltops[]; #ifdef notyet extern struct filterops fifo_rwfiltops[]; -extern struct filterops vn_rwfiltops[]; #endif +extern struct filterops vn_rwfiltops[]; struct filterops kq_rwfiltops[] = { { 1, filt_kqattach, filt_kqdetach, filt_kqueue }, @@ -111,8 +111,8 @@ struct filterops kq_rwfiltops[] = { extern struct filterops sig_filtops; #ifdef notyet extern struct filterops aio_filtops; -extern struct filterops vn_filtops; #endif +extern struct filterops vn_filtops; struct filterops rwtype_filtops = { 1, filt_rwtypattach, NULL, NULL }; @@ -125,7 +125,7 @@ struct filterops proc_filtops = */ struct filterops *rwtypfilt_sw[] = { NULL, /* 0 */ - NULL, /* vn_rwfiltops, */ /* DTYPE_VNODE */ + vn_rwfiltops, /* DTYPE_VNODE */ so_rwfiltops, /* DTYPE_SOCKET */ pipe_rwfiltops, /* DTYPE_PIPE */ /* fifo_rwfiltops, */ /* DTYPE_FIFO */ @@ -139,7 +139,7 @@ struct filterops *sysfilt_ops[] = { &rwtype_filtops, /* EVFILT_READ */ &rwtype_filtops, /* EVFILT_WRITE */ NULL, /*&aio_filtops,*/ /* EVFILT_AIO */ - NULL, /*&vn_filtops,*/ /* EVFILT_VNODE */ + &vn_filtops, /* EVFILT_VNODE */ &proc_filtops, /* EVFILT_PROC */ &sig_filtops, /* EVFILT_SIGNAL */ }; diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index b9435c46086..6bfcf9614ab 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_vnops.c,v 1.26 2000/04/25 02:10:04 deraadt Exp $ */ +/* $OpenBSD: vfs_vnops.c,v 1.27 2000/11/21 21:49:57 provos Exp $ */ /* $NetBSD: vfs_vnops.c,v 1.20 1996/02/04 02:18:41 christos Exp $ */ /* @@ -61,6 +61,9 @@ #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, @@ -73,6 +76,25 @@ int vn_ioctl __P((struct file *fp, u_long com, caddr_t data, 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 }, +}; + /* * Common code for vnode open operations. * Check permissions, and call the VOP_OPEN or VOP_CREATE routine. @@ -508,3 +530,64 @@ 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) + 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) +{ + 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); +} |