diff options
author | jeff <jeff@FreeBSD.org> | 2008-03-31 07:55:45 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2008-03-31 07:55:45 +0000 |
commit | 19683433293d234a790a69f46600e66ef5cbe6d3 (patch) | |
tree | 7894f50da748b21eeef4fcdd7ae757352aa2ecac /sys/ufs | |
parent | 5e4f326d87a3ff8fcfa0d54104443f7c36248506 (diff) | |
download | FreeBSD-src-19683433293d234a790a69f46600e66ef5cbe6d3.zip FreeBSD-src-19683433293d234a790a69f46600e66ef5cbe6d3.tar.gz |
- 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
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 15 |
1 files changed, 4 insertions, 11 deletions
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index dca262c..9a4cb2d 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -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; |