- Since rev 1.142 of ffs_snapshot.c the interlock has not been required

to protect the v_lock pointer.  Removing the interlock acquisition
   here allows vn_lock() to proceed without requiring the interlock
   at all.
 - If the lock mutated while we were sleeping on it the interlock has
   been dropped.  It is conceivable that the upper layer code was
   relying on the interlock and LK_NOWAIT to protect the identity or
   state of the vnode while acquiring the lock.  In this case return
   EBUSY rather than trying the new lock to prevent potential races.

Reviewed by:	tegge
This commit is contained in:
Jeff Roberson 2008-03-31 07:55:45 +00:00
parent 9c0cdb8253
commit d04963d0f4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=177779

View File

@ -361,16 +361,6 @@ ffs_lock(ap)
vp = ap->a_vp;
flags = ap->a_flags;
for (;;) {
/*
* vnode interlock must be held to ensure that
* the possibly external lock isn't freed,
* e.g. when mutating from snapshot file vnode
* to regular file vnode.
*/
if ((flags & LK_INTERLOCK) == 0) {
VI_LOCK(vp);
flags |= LK_INTERLOCK;
}
lkp = vp->v_vnlock;
result = _lockmgr_args(lkp, flags, VI_MTX(vp),
LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT,
@ -385,9 +375,12 @@ ffs_lock(ap)
* right lock. Release it, and try to get the
* new lock.
*/
(void) _lockmgr_args(lkp, LK_RELEASE, VI_MTX(vp),
(void) _lockmgr_args(lkp, LK_RELEASE, NULL,
LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT,
ap->a_file, ap->a_line);
if ((flags & (LK_INTERLOCK | LK_NOWAIT)) ==
(LK_INTERLOCK | LK_NOWAIT))
return (EBUSY);
if ((flags & LK_TYPE_MASK) == LK_UPGRADE)
flags = (flags & ~LK_TYPE_MASK) | LK_EXCLUSIVE;
flags &= ~LK_INTERLOCK;