ping beck@

stacking vp->v_lock (rwlock, couldn't bring myself to call it interlock)
diffs ontop of this to kill v_id and VXLOCK. Could use an eyeball or two :)

On Tue, Jul 11, 2023 at 09:34:01PM +0200, thib4711 wrote:
> deadfs cleanup
> 
> chkvnlock() is useless, since deadfs vops are only ever assigned
> to a vnode at the tail end of vclean(), at which point the VXLOCK
> has been cleared and won't be taken again for this particular
> vnode until it is re-used through getnewvnode().
> 
> As a bonus, LK_DRAIN can soon retire as well.
> Juggle the tail end (mtx enter/leave) and the knote at the tail
> of vclean() for sanity while here.
> 
> diff --git sys/kern/vfs_subr.c sys/kern/vfs_subr.c
> index 650fe5b61a2..425b6871cdd 100644
> --- sys/kern/vfs_subr.c
> +++ sys/kern/vfs_subr.c
> @@ -1051,7 +1051,7 @@ vclean(struct vnode *vp, int flags, struct proc *p)
>        * For active vnodes, it ensures that no other activity can
>        * occur while the underlying object is being cleaned out.
>        */
> -     VOP_LOCK(vp, LK_EXCLUSIVE | LK_DRAIN);
> +     VOP_LOCK(vp, LK_EXCLUSIVE);
>  
>       /*
>        * Clean out any VM data associated with the vnode.
> @@ -1099,19 +1099,21 @@ vclean(struct vnode *vp, int flags, struct proc *p)
>       /*
>        * Done with purge, notify sleepers of the grim news.
>        */
> +     mtx_enter(&vnode_mtx);
>       vp->v_op = &dead_vops;
> -     VN_KNOTE(vp, NOTE_REVOKE);
>       vp->v_tag = VT_NON;
>  #ifdef VFSLCKDEBUG
>       vp->v_flag &= ~VLOCKSWORK;
>  #endif
> -     mtx_enter(&vnode_mtx);
>       vp->v_lflag &= ~VXLOCK;
>       if (vp->v_lflag & VXWANT) {
>               vp->v_lflag &= ~VXWANT;
>               do_wakeup = 1;
>       }
>       mtx_leave(&vnode_mtx);
> +
> +     VN_KNOTE(vp, NOTE_REVOKE);
> +
>       if (do_wakeup)
>               wakeup(vp);
>  }
> diff --git sys/miscfs/deadfs/dead_vnops.c sys/miscfs/deadfs/dead_vnops.c
> index 9711f1618be..44496815567 100644
> --- sys/miscfs/deadfs/dead_vnops.c
> +++ sys/miscfs/deadfs/dead_vnops.c
> @@ -49,16 +49,10 @@ int       dead_ebadf(void *);
>  int  dead_open(void *);
>  int  dead_read(void *);
>  int  dead_write(void *);
> -int  dead_ioctl(void *);
>  int  dead_kqfilter(void *v);
> -int  dead_inactive(void *);
> -int  dead_lock(void *);
> -int  dead_bmap(void *);
>  int  dead_strategy(void *);
>  int  dead_print(void *);
>  
> -int  chkvnlock(struct vnode *);
> -
>  const struct vops dead_vops = {
>       .vop_lookup     = vop_generic_lookup,
>       .vop_create     = vop_generic_badop,
> @@ -70,7 +64,7 @@ const struct vops dead_vops = {
>       .vop_setattr    = dead_ebadf,
>       .vop_read       = dead_read,
>       .vop_write      = dead_write,
> -     .vop_ioctl      = dead_ioctl,
> +     .vop_ioctl      = nullop,
>       .vop_kqfilter   = dead_kqfilter,
>       .vop_revoke     = NULL,
>       .vop_fsync      = nullop,
> @@ -83,12 +77,12 @@ const struct vops dead_vops = {
>       .vop_readdir    = dead_ebadf,
>       .vop_readlink   = dead_ebadf,
>       .vop_abortop    = vop_generic_badop,
> -     .vop_inactive   = dead_inactive,
> +     .vop_inactive   = nullop,
>       .vop_reclaim    = nullop,
> -     .vop_lock       = dead_lock,
> +     .vop_lock       = nullop,
>       .vop_unlock     = nullop,
>       .vop_islocked   = nullop,
> -     .vop_bmap       = dead_bmap,
> +     .vop_bmap       = nullop,
>       .vop_strategy   = dead_strategy,
>       .vop_print      = dead_print,
>       .vop_pathconf   = dead_ebadf,
> @@ -105,50 +99,25 @@ dead_open(void *v)
>       return (ENXIO);
>  }
>  
> -/*
> - * Vnode op for read
> - */
>  int
>  dead_read(void *v)
>  {
>       struct vop_read_args *ap = v;
>  
> -     if (chkvnlock(ap->a_vp))
> -             panic("dead_read: lock");
>       /*
> -      * Return EOF for tty devices, EIO for others
> -      */
> +     * Return EOF for tty devices, EIO for others
> +     */
>       if ((ap->a_vp->v_flag & VISTTY) == 0)
>               return (EIO);
>       return (0);
>  }
>  
> -/*
> - * Vnode op for write
> - */
>  int
>  dead_write(void *v)
>  {
> -     struct vop_write_args *ap = v;
> -
> -     if (chkvnlock(ap->a_vp))
> -             panic("dead_write: lock");
>       return (EIO);
>  }
>  
> -/*
> - * Device ioctl operation.
> - */
> -int
> -dead_ioctl(void *v)
> -{
> -     struct vop_ioctl_args *ap = v;
> -
> -     if (!chkvnlock(ap->a_vp))
> -             return (EBADF);
> -     return ((ap->a_vp->v_op->vop_ioctl)(ap));
> -}
> -
>  int
>  dead_kqfilter(void *v)
>  {
> @@ -180,51 +149,11 @@ dead_strategy(void *v)
>       struct vop_strategy_args *ap = v;
>       int s;
>  
> -     if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) {
> -             ap->a_bp->b_flags |= B_ERROR;
> -             s = splbio();
> -             biodone(ap->a_bp);
> -             splx(s);
> -             return (EIO);
> -     }
> -     return (VOP_STRATEGY(ap->a_bp->b_vp, ap->a_bp));
> -}
> -
> -int
> -dead_inactive(void *v)
> -{
> -     struct vop_inactive_args *ap = v;
> -
> -     VOP_UNLOCK(ap->a_vp);
> -     return (0);
> -}
> -
> -/*
> - * Wait until the vnode has finished changing state.
> - */
> -int
> -dead_lock(void *v)
> -{
> -     struct vop_lock_args *ap = v;
> -     struct vnode *vp = ap->a_vp;
> -
> -     if (ap->a_flags & LK_DRAIN || !chkvnlock(vp))
> -             return (0);
> -
> -     return VOP_LOCK(vp, ap->a_flags);
> -}
> -
> -/*
> - * Wait until the vnode has finished changing state.
> - */
> -int
> -dead_bmap(void *v)
> -{
> -     struct vop_bmap_args *ap = v;
> -
> -     if (!chkvnlock(ap->a_vp))
> -             return (EIO);
> -     return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp));
> +     ap->a_bp->b_flags |= B_ERROR;
> +     s = splbio();
> +     biodone(ap->a_bp);
> +     splx(s);
> +     return (EIO);
>  }
>  
>  /*
> @@ -234,7 +163,7 @@ int
>  dead_print(void *v)
>  {
>       printf("tag VT_NON, dead vnode\n");
> -     return 0;
> +     return (0);
>  }
>  
>  /*
> @@ -245,22 +174,3 @@ dead_ebadf(void *v)
>  {
>       return (EBADF);
>  }
> -
> -/*
> - * We have to wait during times when the vnode is
> - * in a state of change.
> - */
> -int
> -chkvnlock(struct vnode *vp)
> -{
> -     int locked = 0;
> -
> -     mtx_enter(&vnode_mtx);
> -     while (vp->v_lflag & VXLOCK) {
> -             vp->v_lflag |= VXWANT;
> -             msleep_nsec(vp, &vnode_mtx, PINOD, "chkvnlock", INFSLP);
> -             locked = 1;
> -     }
> -     mtx_leave(&vnode_mtx);
> -     return (locked);
> -}
> 

Reply via email to