summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_vnops.c
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2000-04-16 18:53:38 +0000
committerjlemon <jlemon@FreeBSD.org>2000-04-16 18:53:38 +0000
commitc41c876463ee8c302f06554537e0fb22a3fcdca4 (patch)
treed2f87a6af04c4f35f243bf580d099496a4131330 /sys/kern/vfs_vnops.c
parentf8f9ad64d408b963d98d0e11b37e871763557e95 (diff)
downloadFreeBSD-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.c77
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);
+}
OpenPOWER on IntegriCloud