svn commit: r210173 - in stable/7/sys: cddl/contrib/opensolaris/uts/common/fs/zfs fs/cd9660 fs/udf ufs/ffs

John Baldwin jhb at FreeBSD.org
Fri Jul 16 20:23:25 UTC 2010


Author: jhb
Date: Fri Jul 16 20:23:24 2010
New Revision: 210173
URL: http://svn.freebsd.org/changeset/base/210173

Log:
  When the MNTK_EXTENDED_SHARED mount option was added, some filesystems were
  changed to defer the setting of VN_LOCK_ASHARE() (which clears LK_NOSHARE
  in the vnode lock's flags) until after they had determined if the vnode was
  a FIFO.  This occurs after the vnode has been inserted into a VFS hash or
  some similar table, so it is possible for another thread to find this vnode
  via vget() on an i-node number and block on the vnode lock.  If the lockmgr
  interlock (vnode interlock for vnode locks) is not held when clearing the
  LK_NOSHARE flag, then the lk_flags field can be clobbered.  As a result
  the thread blocked on the vnode lock may never get woken up.  Fix this by
  holding the vnode interlock while modifying the lock flags in this case.
  
  The softupdates code also toggles LK_NOSHARE in one function to close a
  race with snapshots.  Fix this code to grab the interlock while fiddling
  with lk_flags.

Modified:
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
  stable/7/sys/fs/cd9660/cd9660_vfsops.c
  stable/7/sys/fs/udf/udf_vfsops.c
  stable/7/sys/ufs/ffs/ffs_softdep.c
  stable/7/sys/ufs/ffs/ffs_vfsops.c

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c	Fri Jul 16 19:52:03 2010	(r210172)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c	Fri Jul 16 20:23:24 2010	(r210173)
@@ -618,8 +618,11 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_bu
 		vp->v_op = &zfs_fifoops;
 		break;
 	}
-	if (vp->v_type != VFIFO)
+	if (vp->v_type != VFIFO) {
+		VI_LOCK(vp);
 		VN_LOCK_ASHARE(vp);
+		VI_UNLOCK(vp);
+	}
 
 	mutex_enter(&zfsvfs->z_znodes_lock);
 	list_insert_tail(&zfsvfs->z_all_znodes, zp);

Modified: stable/7/sys/fs/cd9660/cd9660_vfsops.c
==============================================================================
--- stable/7/sys/fs/cd9660/cd9660_vfsops.c	Fri Jul 16 19:52:03 2010	(r210172)
+++ stable/7/sys/fs/cd9660/cd9660_vfsops.c	Fri Jul 16 20:23:24 2010	(r210173)
@@ -821,7 +821,9 @@ cd9660_vget_internal(mp, ino, flags, vpp
 		vp->v_op = &cd9660_fifoops;
 		break;
 	default:
-		vp->v_vnlock->lk_flags &= ~LK_NOSHARE;
+		VI_LOCK(vp);
+		VN_LOCK_ASHARE(vp);
+		VI_UNLOCK(vp);
 		break;
 	}
 

Modified: stable/7/sys/fs/udf/udf_vfsops.c
==============================================================================
--- stable/7/sys/fs/udf/udf_vfsops.c	Fri Jul 16 19:52:03 2010	(r210172)
+++ stable/7/sys/fs/udf/udf_vfsops.c	Fri Jul 16 20:23:24 2010	(r210173)
@@ -709,8 +709,11 @@ udf_vget(struct mount *mp, ino_t ino, in
 		break;
 	}
 
-	if (vp->v_type != VFIFO)
+	if (vp->v_type != VFIFO) {
+		VI_LOCK(vp);
 		VN_LOCK_ASHARE(vp);
+		VI_UNLOCK(vp);
+	}
 
 	if (ino == udf_getid(&udfmp->root_icb))
 		vp->v_vflag |= VV_ROOT;

Modified: stable/7/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- stable/7/sys/ufs/ffs/ffs_softdep.c	Fri Jul 16 19:52:03 2010	(r210172)
+++ stable/7/sys/ufs/ffs/ffs_softdep.c	Fri Jul 16 20:23:24 2010	(r210173)
@@ -5291,7 +5291,9 @@ top:
 		return (0);
 loop:
 	/* While syncing snapshots, we must allow recursive lookups */
+	mtx_lock(bp->b_lock.lk_interlock);
 	bp->b_lock.lk_flags |= LK_CANRECURSE;
+	mtx_unlock(bp->b_lock.lk_interlock);
 	ACQUIRE_LOCK(&lk);
 	/*
 	 * As we hold the buffer locked, none of its dependencies
@@ -5433,7 +5435,9 @@ loop:
 		/* We reach here only in error and unlocked */
 		if (error == 0)
 			panic("softdep_sync_metadata: zero error");
+		mtx_lock(bp->b_lock.lk_interlock);
 		bp->b_lock.lk_flags &= ~LK_CANRECURSE;
+		mtx_unlock(bp->b_lock.lk_interlock);
 		bawrite(bp);
 		return (error);
 	}
@@ -5445,7 +5449,9 @@ loop:
 			break;
 	}
 	VI_UNLOCK(vp);
+	mtx_lock(bp->b_lock.lk_interlock);
 	bp->b_lock.lk_flags &= ~LK_CANRECURSE;
+	mtx_unlock(bp->b_lock.lk_interlock);
 	bawrite(bp);
 	if (nbp != NULL) {
 		bp = nbp;

Modified: stable/7/sys/ufs/ffs/ffs_vfsops.c
==============================================================================
--- stable/7/sys/ufs/ffs/ffs_vfsops.c	Fri Jul 16 19:52:03 2010	(r210172)
+++ stable/7/sys/ufs/ffs/ffs_vfsops.c	Fri Jul 16 20:23:24 2010	(r210173)
@@ -1519,7 +1519,9 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags
 	 */
 	if (vp->v_type != VFIFO) {
 		/* FFS supports shared locking for all files except fifos. */
+		VI_LOCK(vp);
 		VN_LOCK_ASHARE(vp);
+		VI_UNLOCK(vp);
 	}
 
 	/*


More information about the svn-src-stable-7 mailing list