diff options
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r-- | sys/kern/vfs_subr.c | 72 |
1 files changed, 49 insertions, 23 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 1697696..92cb025 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -98,6 +98,10 @@ static void vfree(struct vnode *); static void vnlru_free(int); static void vdestroy(struct vnode *); static void vgonel(struct vnode *); +static void vfs_knllock(void *arg); +static void vfs_knlunlock(void *arg); +static int vfs_knllocked(void *arg); + /* * Enable Giant pushdown based on whether or not the vm is mpsafe in this @@ -2834,8 +2838,8 @@ v_addpollinfo(struct vnode *vp) } vp->v_pollinfo = vi; mtx_init(&vp->v_pollinfo->vpi_lock, "vnode pollinfo", NULL, MTX_DEF); - knlist_init(&vp->v_pollinfo->vpi_selinfo.si_note, - &vp->v_pollinfo->vpi_lock); + knlist_init(&vp->v_pollinfo->vpi_selinfo.si_note, vp, vfs_knllock, + vfs_knlunlock, vfs_knllocked); } /* @@ -3473,7 +3477,7 @@ vop_create_post(void *ap, int rc) struct vop_create_args *a = ap; if (!rc) - VFS_SEND_KNOTE(a->a_dvp, NOTE_WRITE); + VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE); } void @@ -3482,8 +3486,8 @@ vop_link_post(void *ap, int rc) struct vop_link_args *a = ap; if (!rc) { - VFS_SEND_KNOTE(a->a_vp, NOTE_LINK); - VFS_SEND_KNOTE(a->a_tdvp, NOTE_WRITE); + VFS_KNOTE_LOCKED(a->a_vp, NOTE_LINK); + VFS_KNOTE_LOCKED(a->a_tdvp, NOTE_WRITE); } } @@ -3493,7 +3497,7 @@ vop_mkdir_post(void *ap, int rc) struct vop_mkdir_args *a = ap; if (!rc) - VFS_SEND_KNOTE(a->a_dvp, NOTE_WRITE | NOTE_LINK); + VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE | NOTE_LINK); } void @@ -3502,7 +3506,7 @@ vop_mknod_post(void *ap, int rc) struct vop_mknod_args *a = ap; if (!rc) - VFS_SEND_KNOTE(a->a_dvp, NOTE_WRITE); + VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE); } void @@ -3511,8 +3515,8 @@ vop_remove_post(void *ap, int rc) struct vop_remove_args *a = ap; if (!rc) { - VFS_SEND_KNOTE(a->a_dvp, NOTE_WRITE); - VFS_SEND_KNOTE(a->a_vp, NOTE_DELETE); + VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE); + VFS_KNOTE_LOCKED(a->a_vp, NOTE_DELETE); } } @@ -3522,11 +3526,11 @@ vop_rename_post(void *ap, int rc) struct vop_rename_args *a = ap; if (!rc) { - VFS_SEND_KNOTE(a->a_fdvp, NOTE_WRITE); - VFS_SEND_KNOTE(a->a_tdvp, NOTE_WRITE); - VFS_SEND_KNOTE(a->a_fvp, NOTE_RENAME); + VFS_KNOTE_UNLOCKED(a->a_fdvp, NOTE_WRITE); + VFS_KNOTE_UNLOCKED(a->a_tdvp, NOTE_WRITE); + VFS_KNOTE_UNLOCKED(a->a_fvp, NOTE_RENAME); if (a->a_tvp) - VFS_SEND_KNOTE(a->a_tvp, NOTE_DELETE); + VFS_KNOTE_UNLOCKED(a->a_tvp, NOTE_DELETE); } if (a->a_tdvp != a->a_fdvp) vdrop(a->a_fdvp); @@ -3543,8 +3547,8 @@ vop_rmdir_post(void *ap, int rc) struct vop_rmdir_args *a = ap; if (!rc) { - VFS_SEND_KNOTE(a->a_dvp, NOTE_WRITE | NOTE_LINK); - VFS_SEND_KNOTE(a->a_vp, NOTE_DELETE); + VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE | NOTE_LINK); + VFS_KNOTE_LOCKED(a->a_vp, NOTE_DELETE); } } @@ -3554,7 +3558,7 @@ vop_setattr_post(void *ap, int rc) struct vop_setattr_args *a = ap; if (!rc) - VFS_SEND_KNOTE(a->a_vp, NOTE_ATTRIB); + VFS_KNOTE_LOCKED(a->a_vp, NOTE_ATTRIB); } void @@ -3563,7 +3567,7 @@ vop_symlink_post(void *ap, int rc) struct vop_symlink_args *a = ap; if (!rc) - VFS_SEND_KNOTE(a->a_dvp, NOTE_WRITE); + VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE); } static struct knlist fs_knlist; @@ -3571,7 +3575,7 @@ static struct knlist fs_knlist; static void vfs_event_init(void *arg) { - knlist_init(&fs_knlist, NULL); + knlist_init(&fs_knlist, NULL, NULL, NULL, NULL); } /* XXX - correct order? */ SYSINIT(vfs_knlist, SI_SUB_VFS, SI_ORDER_ANY, vfs_event_init, NULL); @@ -3658,7 +3662,6 @@ static int filt_vfsread(struct knote *kn, long hint); static int filt_vfswrite(struct knote *kn, long hint); static int filt_vfsvnode(struct knote *kn, long hint); static void filt_vfsdetach(struct knote *kn); - static struct filterops vfsread_filtops = { 1, NULL, filt_vfsdetach, filt_vfsread }; static struct filterops vfswrite_filtops = @@ -3666,11 +3669,36 @@ static struct filterops vfswrite_filtops = static struct filterops vfsvnode_filtops = { 1, NULL, filt_vfsdetach, filt_vfsvnode }; +static void +vfs_knllock(void *arg) +{ + struct vnode *vp = arg; + + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread); +} + +static void +vfs_knlunlock(void *arg) +{ + struct vnode *vp = arg; + + VOP_UNLOCK(vp, 0, curthread); +} + +static int +vfs_knllocked(void *arg) +{ + struct vnode *vp = arg; + + return (VOP_ISLOCKED(vp, curthread) == LK_EXCLUSIVE); +} + int vfs_kqfilter(struct vop_kqfilter_args *ap) { struct vnode *vp = ap->a_vp; struct knote *kn = ap->a_kn; + struct knlist *knl; switch (kn->kn_filter) { case EVFILT_READ: @@ -3692,7 +3720,8 @@ vfs_kqfilter(struct vop_kqfilter_args *ap) v_addpollinfo(vp); if (vp->v_pollinfo == NULL) return (ENOMEM); - knlist_add(&vp->v_pollinfo->vpi_selinfo.si_note, kn, 0); + knl = &vp->v_pollinfo->vpi_selinfo.si_note; + knlist_add(knl, kn, 0); return (0); } @@ -3725,11 +3754,8 @@ filt_vfsread(struct knote *kn, long hint) return (1); } - vn_lock(vp, LK_SHARED | LK_RETRY, curthread); if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread)) return (0); - if (VOP_UNLOCK(vp, 0, curthread)) - return (0); kn->kn_data = va.va_size - kn->kn_fp->f_offset; return (kn->kn_data != 0); |