summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2008-03-31 07:55:45 +0000
committerjeff <jeff@FreeBSD.org>2008-03-31 07:55:45 +0000
commit19683433293d234a790a69f46600e66ef5cbe6d3 (patch)
tree7894f50da748b21eeef4fcdd7ae757352aa2ecac /sys/ufs
parent5e4f326d87a3ff8fcfa0d54104443f7c36248506 (diff)
downloadFreeBSD-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.c15
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;
OpenPOWER on IntegriCloud