diff options
author | jeff <jeff@FreeBSD.org> | 2002-08-22 06:58:11 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2002-08-22 06:58:11 +0000 |
commit | 820f26ad86899f246ecf708829e33ae1eb8b0bf7 (patch) | |
tree | eb99fb2547185035938ae7bdb4a87f96c795345b /sys/kern/vfs_vnops.c | |
parent | 1e39ba86206301d7f569b3f402577d596d55faa0 (diff) | |
download | FreeBSD-src-820f26ad86899f246ecf708829e33ae1eb8b0bf7.zip FreeBSD-src-820f26ad86899f246ecf708829e33ae1eb8b0bf7.tar.gz |
- Fix interlock handling in vn_lock(). Previously, vn_lock() could return
with interlock held in error conditions when the caller did not specify
LK_INTERLOCK.
- Add several comments to vn_lock() describing the rational behind the code
flow since it was not immediately obvious.
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r-- | sys/kern/vfs_vnops.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 875e3f0..3f00fda 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -843,25 +843,27 @@ debug_vn_lock(vp, flags, td, filename, line) vp->v_iflag |= VI_XWANT; msleep(vp, VI_MTX(vp), PINOD | PDROP, "vn_lock", 0); - mp_fixme("interlock not released."); + /* + * Since we're just going to return, unlock interlock + * if the caller didn't call us with it held. + */ + if ((flags & (LK_INTERLOCK|LK_RETRY)) == 0) + VI_UNLOCK(vp); error = ENOENT; } else { -#if 0 - /* this can now occur in normal operation */ - if (vp->v_vxproc != NULL) - log(LOG_INFO, "VXLOCK interlock avoided in vn_lock\n"); -#endif #ifdef DEBUG_LOCKS vp->filename = filename; vp->line = line; #endif + /* + * lockmgr drops interlock before it will return for + * any reason. So force the code above to relock it. + */ error = VOP_LOCK(vp, flags | LK_NOPAUSE | LK_INTERLOCK, td); - if (error == 0) - return (error); + flags &= ~LK_INTERLOCK; } - flags &= ~LK_INTERLOCK; - } while (flags & LK_RETRY); + } while (flags & LK_RETRY && error != 0); return (error); } |