Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Aug 2007 11:35:06 +0300
From:      Kostik Belousov <kostikbel@gmail.com>
To:        Xin LI <delphij@freebsd.org>
Cc:        cvs-src@freebsd.org, src-committers@freebsd.org, cvs-all@freebsd.org
Subject:   Re: [src] cvs commit: src/sys/fs/tmpfs tmpfs.h tmpfs_subr.c tmpfs_vfsops.c tmpfs_vnops.c
Message-ID:  <20070810083506.GS2738@deviant.kiev.zoral.com.ua>
In-Reply-To: <20070810052455.0B4B716A4F4@hub.freebsd.org>
References:  <200708100524.l7A5OnE4065132@repoman.freebsd.org> <20070810052455.0B4B716A4F4@hub.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--UPvCt0eiAD9X+G9u
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Fri, Aug 10, 2007 at 05:24:54AM +0000, Xin LI wrote:
> delphij     2007-08-10 05:24:49 UTC
>=20
>   FreeBSD src repository
>=20
>   Modified files:
>     sys/fs/tmpfs         tmpfs.h tmpfs_subr.c tmpfs_vfsops.c=20
>                          tmpfs_vnops.c=20
>   Log:
>   MFp4:
>  =20
>    - Respect cnflag and don't lock vnode always as LK_EXCLUSIVE [1]
>    - Properly lock around tn_vnode to avoid NULL deference
>    - Be more careful handling vnodes (*)
>  =20
>   (*) This is a WIP
>   [1] by pjd via howardsu
>  =20
>   Thanks kib@ for his valuable VFS related comments.
>  =20
>   Tested with:    fsx, fstest, tmpfs regression test set
>   Found by:       pho's stress2 suite
>   Approved by:    re (tmpfs blanket)
>  =20
>   Revision  Changes    Path
>   1.10      +2 -2      src/sys/fs/tmpfs/tmpfs.h
>   1.11      +28 -19    src/sys/fs/tmpfs/tmpfs_subr.c
>   1.9       +5 -2      src/sys/fs/tmpfs/tmpfs_vfsops.c
>   1.9       +34 -13    src/sys/fs/tmpfs/tmpfs_vnops.c

> Index: src/sys/fs/tmpfs/tmpfs_subr.c
> diff -u src/sys/fs/tmpfs/tmpfs_subr.c:1.10 src/sys/fs/tmpfs/tmpfs_subr.c:=
1.11
> --- src/sys/fs/tmpfs/tmpfs_subr.c:1.10	Fri Aug  3 06:24:31 2007
> +++ src/sys/fs/tmpfs/tmpfs_subr.c	Fri Aug 10 05:24:49 2007
> @@ -302,15 +308,20 @@
>   * Returns zero on success or an appropriate error code on failure.
>   */
>  int
> -tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, struct vnode *=
*vpp,
> -    struct thread *td)
> +tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag,
> +    struct vnode **vpp, struct thread *td)
>  {
>  	int error;
>  	struct vnode *vp;
> =20
>  loop:
> +	TMPFS_NODE_LOCK(node);
>  	if ((vp =3D node->tn_vnode) !=3D NULL) {
> -		error =3D vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
> +		VI_LOCK(vp);
> +		TMPFS_NODE_UNLOCK(node);
> +		vholdl(vp);
> +		error =3D vget(vp, lkflag | LK_INTERLOCK | LK_RETRY, td);
> +		vdrop(vp);
>  		if (error)
>  			return error;
LK_RETRY prohibits the vget() and vn_lock() to return error.

> Index: src/sys/fs/tmpfs/tmpfs_vnops.c
> diff -u src/sys/fs/tmpfs/tmpfs_vnops.c:1.8 src/sys/fs/tmpfs/tmpfs_vnops.c=
:1.9
> --- src/sys/fs/tmpfs/tmpfs_vnops.c:1.8	Thu Jul 19 03:34:50 2007
> +++ src/sys/fs/tmpfs/tmpfs_vnops.c	Fri Aug 10 05:24:49 2007
> @@ -95,12 +95,20 @@
>  	    !(cnp->cn_flags & ISDOTDOT)));
> =20
>  	if (cnp->cn_flags & ISDOTDOT) {
> -		VOP_UNLOCK(dvp, 0, td);
> +		int ltype =3D 0;
> =20
> +		ltype =3D VOP_ISLOCKED(dvp, td);
> +		vholdl(dvp);
vholdl() assumes that vnode interlock is locked, not vnode itself. You shall
use vhold() when not holding vnode interlock.

Later, you use dvp->v_mount, that could change to NULL once you dropped the
dvp lock. Moreover, filesystem may be unmounted after you dropped vnode
lock. UFS has the same problem.

> +		VOP_UNLOCK(dvp, 0, td);
>  		/* Allocate a new vnode on the matching entry. */
> -		error =3D tmpfs_alloc_vp(dvp->v_mount, dnode->tn_dir.tn_parent, vpp, t=
d);
> +		error =3D tmpfs_alloc_vp(dvp->v_mount, dnode->tn_dir.tn_parent,
> +		    cnp->cn_lkflags, vpp, td);
> =20
> -		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
> +		vn_lock(dvp, ltype | LK_RETRY, td);
> +		if (ltype & LK_INTERLOCK)
> +			vdropl(dvp);
> +		else
> +			vdrop(dvp);
ltype cannot contain LK_INTERLOCK flag. Moreover, vn_lock() always returns
with interlock being dropped. You shall simply vdrop(dvp) there.

> =20
>  		dnode->tn_dir.tn_parent->tn_lookup_dirent =3D NULL;
>  	} else if (cnp->cn_namelen =3D=3D 1 && cnp->cn_nameptr[0] =3D=3D '.') {

--UPvCt0eiAD9X+G9u
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (FreeBSD)

iD8DBQFGvCM6C3+MBN1Mb4gRAvnKAJ4yBFu81yAdm3/aRM/mTEACvDJMXgCgpqJZ
i3Ykfautlu8xg7/BDasOMYk=
=rpuw
-----END PGP SIGNATURE-----

--UPvCt0eiAD9X+G9u--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070810083506.GS2738>