summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2001-02-15 16:34:11 +0000
committerjlemon <jlemon@FreeBSD.org>2001-02-15 16:34:11 +0000
commit11781a7431fab609cd00058a63ac09ccddb16854 (patch)
treeee46dbf40488c941cf17b05e69bfe21e4f2d7128 /sys/ufs
parent5655168b87e22a331c5fc3b603901647ff90b2e4 (diff)
downloadFreeBSD-src-11781a7431fab609cd00058a63ac09ccddb16854.zip
FreeBSD-src-11781a7431fab609cd00058a63ac09ccddb16854.tar.gz
Extend kqueue down to the device layer.
Backwards compatible approach suggested by: peter
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ufs/ufs_vnops.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 134e356..2244df3 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -61,6 +61,8 @@
#include <machine/mutex.h>
+#include <sys/file.h> /* XXX */
+
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -103,6 +105,10 @@ static int ufsfifo_write __P((struct vop_write_args *));
static int ufsspec_close __P((struct vop_close_args *));
static int ufsspec_read __P((struct vop_read_args *));
static int ufsspec_write __P((struct vop_write_args *));
+static int filt_ufsread __P((struct knote *kn, long hint));
+static int filt_ufsvnode __P((struct knote *kn, long hint));
+static void filt_ufsdetach __P((struct knote *kn));
+static int ufs_kqfilter __P((struct vop_kqfilter_args *ap));
union _qcvt {
int64_t qcvt;
@@ -2176,6 +2182,71 @@ ufs_missingop(ap)
return (EOPNOTSUPP);
}
+static struct filterops ufsread_filtops =
+ { 1, NULL, filt_ufsdetach, filt_ufsread };
+static struct filterops ufsvnode_filtops =
+ { 1, NULL, filt_ufsdetach, filt_ufsvnode };
+
+static int
+ufs_kqfilter(ap)
+ struct vop_kqfilter_args /* {
+ struct vnode *a_vp;
+ struct knote *a_kn;
+ } */ *ap;
+{
+ struct vnode *vp = ap->a_vp;
+ struct knote *kn = ap->a_kn;
+
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_fop = &ufsread_filtops;
+ break;
+ case EVFILT_VNODE:
+ kn->kn_fop = &ufsvnode_filtops;
+ break;
+ default:
+ return (1);
+ }
+
+ kn->kn_hook = (caddr_t)vp;
+
+ mtx_lock(&vp->v_pollinfo.vpi_lock);
+ SLIST_INSERT_HEAD(&vp->v_pollinfo.vpi_selinfo.si_note, kn, kn_selnext);
+ mtx_unlock(&vp->v_pollinfo.vpi_lock);
+
+ return (0);
+}
+
+static void
+filt_ufsdetach(struct knote *kn)
+{
+ struct vnode *vp = (struct vnode *)kn->kn_hook;
+
+ mtx_lock(&vp->v_pollinfo.vpi_lock);
+ SLIST_REMOVE(&vp->v_pollinfo.vpi_selinfo.si_note, kn, knote, kn_link);
+ mtx_unlock(&vp->v_pollinfo.vpi_lock);
+}
+
+/*ARGSUSED*/
+static int
+filt_ufsread(struct knote *kn, long hint)
+{
+ struct vnode *vp = (struct vnode *)kn->kn_hook;
+ struct inode *ip = VTOI(vp);
+
+ kn->kn_data = ip->i_size - kn->kn_fp->f_offset;
+ return (kn->kn_data != 0);
+}
+
+static int
+filt_ufsvnode(struct knote *kn, long hint)
+{
+
+ if (kn->kn_sfflags & hint)
+ kn->kn_fflags |= hint;
+ return (kn->kn_fflags != 0);
+}
+
/* Global vfs data structures for ufs. */
static vop_t **ufs_vnodeop_p;
static struct vnodeopv_entry_desc ufs_vnodeop_entries[] = {
@@ -2201,6 +2272,7 @@ static struct vnodeopv_entry_desc ufs_vnodeop_entries[] = {
{ &vop_open_desc, (vop_t *) ufs_open },
{ &vop_pathconf_desc, (vop_t *) ufs_pathconf },
{ &vop_poll_desc, (vop_t *) vop_stdpoll },
+ { &vop_kqfilter_desc, (vop_t *) ufs_kqfilter },
{ &vop_getwritemount_desc, (vop_t *) vop_stdgetwritemount },
{ &vop_print_desc, (vop_t *) ufs_print },
{ &vop_readdir_desc, (vop_t *) ufs_readdir },
OpenPOWER on IntegriCloud