Locking bug in vget()?
Locking bug in vget()?
- Subject: Locking bug in vget()?
- From: Brian Bergstrand <email@hidden>
- Date: Sun, 9 Mar 2003 01:21:33 -0600
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I think I may have found a bug in vget().
Here is the code from vfs_subr.c:1.1.1.6
int
vget(vp, flags, p)
struct vnode *vp;
int flags;
struct proc *p;
{
int error = 0;
retry:
/*
* If the vnode is in the process of being cleaned out for
* another use, we wait for the cleaning to finish and then
* return failure. Cleaning is determined by checking that
* the VXLOCK flag is set.
*/
if ((flags & LK_INTERLOCK) == 0)
simple_lock(&vp->v_interlock);
if ((vp->v_flag & VXLOCK) || (vp->v_flag & VORECLAIM)) {
vp->v_flag |= VXWANT;
simple_unlock(&vp->v_interlock);
(void)tsleep((caddr_t)vp, PINOD, "vget", 0);
return (ENOENT);
}
/*
* vnode is being terminated.
* wait for vnode_pager_no_senders() to clear VTERMINATE
*/
if (ISSET(vp->v_flag, VTERMINATE)) {
SET(vp->v_flag, VTERMWANT);
simple_unlock(&vp->v_interlock);
(void)tsleep((caddr_t)&vp->v_ubcinfo, PINOD, "vclean", 0);
return (ENOENT);
}
/*
* if the vnode is being initialized,
* wait for it to finish initialization
*/
if (ISSET(vp->v_flag, VUINIT)) {
if (ISSET(vp->v_flag, VUINIT)) {
SET(vp->v_flag, VUWANT);
simple_unlock(&vp->v_interlock);
(void) tsleep((caddr_t)vp, PINOD, "vget2", 0);
goto retry;
}
}
...
In the last case [ if (ISSET(vp->v_flag, VUINIT)) ], where the thread
sleeps waiting for the VNODE to finish init, the interlock is dropped
before waiting, but after returning from the wait it jumps immediately
to retry: w/o checking flags for LK_INTERLOCK. If LK_INTERLOCK is set,
then the interlock won't be acquired at the beginning of retry:. Maybe
I'm missing something, but before going to retry, shouldn't
LK_INTERLOCK be cleared or if set then then re-acquire the lock before
the jump?
Something like this:
/*
* if the vnode is being initialized,
* wait for it to finish initialization
*/
if (ISSET(vp->v_flag, VUINIT)) {
if (ISSET(vp->v_flag, VUINIT)) {
SET(vp->v_flag, VUWANT);
simple_unlock(&vp->v_interlock);
(void) tsleep((caddr_t)vp, PINOD, "vget2", 0);
flags &= ~LK_INTERLOCK;
goto retry;
}
}
Brian Bergstrand
<
http://www.classicalguitar.net/brian/> PGP Key ID: 0xB6C7B6A2
We are not retreating - we are advancing in another direction. -
General Douglas MacArthur
-----BEGIN PGP SIGNATURE-----
Version: PGP 8.0
iQA/AwUBPmrdjHnR2Fu2x7aiEQK3DwCg4ysw54MxU0zrNpWMn7lQy8a2EmQAn3qO
dBTnYTyYAMdbpmiHNKY+t8Ao
=Qm9E
-----END PGP SIGNATURE-----
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.