Subject: Re: reboot problems unmounting root
To: Antti Kantee , Juan RP <juan@xtrarom.org>
From: Andrew Doran <ad@netbsd.org>
List: tech-userlevel
Date: 07/05/2007 10:07:20
On Thu, Jul 05, 2007 at 12:02:57PM +0300, Antti Kantee wrote:

> Index: genfs/layer_vnops.c
> ===================================================================
> RCS file: /cvsroot/src/sys/miscfs/genfs/layer_vnops.c,v
> retrieving revision 1.31
> diff -u -r1.31 layer_vnops.c
> --- genfs/layer_vnops.c	16 Apr 2007 08:10:58 -0000	1.31
> +++ genfs/layer_vnops.c	5 Jul 2007 09:02:38 -0000
> @@ -741,6 +741,7 @@
>  		struct lwp *a_l;
>  	} */ *ap = v;
>  	struct vnode *vp = ap->a_vp;
> +	int vxlock;
>  
>  	/*
>  	 * Do nothing (and _don't_ bypass).
> @@ -756,12 +757,19 @@
>  	 */
>  	VOP_UNLOCK(vp, 0);
>  
> +	simple_lock(&vp->v_interlock);
> +	vxlock = vp->v_flag & VXLOCK;
> +	simple_unlock(&vp->v_interlock);
> +
>  	/*
>  	 * ..., but don't cache the device node. Also, if we did a
> -	 * remove, don't cache the node.
> +	 * remove, don't cache the node.  Finally, if the node is
> +	 * already being nuked, don't do this, as we would re-enter
> +	 * the same path and deadlock.
>  	 */
> -	if (vp->v_type == VBLK || vp->v_type == VCHR
> +	if ((vp->v_type == VBLK || vp->v_type == VCHR
>  	    || (VTOLAYER(vp)->layer_flags & LAYERFS_REMOVED))
> +	  && (vxlock == 0))
>  		vgone(vp);
>  	return (0);
>  }

I think it's better to hold the interlock across the if statement and do
a vgonel() instead.

Andrew