Subject: Re: LK_RETRY and coda_lookup
To: Greg Troxel <gdt@ir.bbn.com>
From: Bill Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 03/12/2006 14:14:33
--JgQwtEuHJzHdouWu
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
On Tue, Feb 28, 2006 at 12:38:30PM -0500, Greg Troxel wrote:
> In src/sys/coda/coda_vnops.c 1.46, I added LK_RETRY to vn_lock calls.
> This seems correct because vn_lock will (absent LK_RETRY) fail if the
> vnode is already locked (presumably by another thread), but it will
> first sleep until a wakeup happens.
Sorry for the delay, but I think tis is wrong.
> 1) Am I correct that some other process could have VXLOCK on the
> vnode, that this is really a normal condition, and thus that
> LK_RETRY is really in order? (I would think LK_RETRY should only
> be omitted as part of some deadlock avoidance procedure where the
> calling code is doing retries, or something like that.)
VXLOCK should only be used when we are recycling the vnode - when we are=20
blowing it away. It is set when we are changing the type of the vnode, in=
=20
part as all of the locking originally was done by the fs.
> 2) Why does vn_lock sleep if it's going to fail? Is this for
> caller-managed retry loops?
To wait for the cleanup to finish, I expect.
> 3) For clarity, it seems that LK_INTERLOCK should be cleared after
> ltsleep, and separately after VOP_LOCK. I realize this is a case
> of CSE but it makes it harder to realize that the rules are being
> followed.
If I understand the code right, I think it's a style thing. We go through=
=20
one or the other side of an if statement, and we clear it after the if.
> Any clues appreciated.
>=20
>=20
> vn_lock body from src/sys/kern/vfs_vnops.c:
>=20
> do {
> if ((flags & LK_INTERLOCK) =3D=3D 0)
> simple_lock(&vp->v_interlock);
> if (vp->v_flag & VXLOCK) {
> if (flags & LK_NOWAIT) {
> simple_unlock(&vp->v_interlock);
> return EBUSY;
> }
> vp->v_flag |=3D VXWANT;
> ltsleep(vp, PINOD | PNORELOCK,
> "vn_lock", 0, &vp->v_interlock);
> error =3D ENOENT;
> } else {
> error =3D VOP_LOCK(vp,
> (flags & ~LK_RETRY) | LK_INTERLOCK);
> if (error =3D=3D 0 || error =3D=3D EDEADLK || error =3D=3D EBUSY)
> return (error);
> }
> flags &=3D ~LK_INTERLOCK;
> } while (flags & LK_RETRY);
Or did I miss something? :-)
The only case I can see where it isn't cleared is if we trigger the return=
=20
after VOP_LOCK(). But in that case, since flags is local, it no longer=20
matters.
Take care,
Bill
--JgQwtEuHJzHdouWu
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (NetBSD)
iD8DBQFEFJ1JWz+3JHUci9cRAimbAJ9ILH4RI8DSbByOWlkuZQVYtK+z5gCfdW+I
xda34qhxFI1guc5wD7mHQYw=
=9cgt
-----END PGP SIGNATURE-----
--JgQwtEuHJzHdouWu--