Subject: LK_RETRY and coda_lookup
To: None <tech-kern@netbsd.org>
From: Greg Troxel <gdt@ir.bbn.com>
List: tech-kern
Date: 02/28/2006 12:38:30
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.

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.)

2) Why does vn_lock sleep if it's going to fail?  Is this for
   caller-managed retry loops?

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.


Any clues appreciated.


vn_lock body from src/sys/kern/vfs_vnops.c:

	do {
		if ((flags & LK_INTERLOCK) == 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 |= VXWANT;
			ltsleep(vp, PINOD | PNORELOCK,
			    "vn_lock", 0, &vp->v_interlock);
			error = ENOENT;
		} else {
			error = VOP_LOCK(vp,
			    (flags & ~LK_RETRY) | LK_INTERLOCK);
			if (error == 0 || error == EDEADLK || error == EBUSY)
				return (error);
		}
		flags &= ~LK_INTERLOCK;
	} while (flags & LK_RETRY);