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);
> -}
>