From owner-svn-src-stable@FreeBSD.ORG Fri Jul 16 20:23:25 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 53C8E1065673; Fri, 16 Jul 2010 20:23:25 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 41D998FC0C; Fri, 16 Jul 2010 20:23:25 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o6GKNP3l012509; Fri, 16 Jul 2010 20:23:25 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o6GKNP18012503; Fri, 16 Jul 2010 20:23:25 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201007162023.o6GKNP18012503@svn.freebsd.org> From: John Baldwin Date: Fri, 16 Jul 2010 20:23:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210173 - in stable/7/sys: cddl/contrib/opensolaris/uts/common/fs/zfs fs/cd9660 fs/udf ufs/ffs X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Jul 2010 20:23:25 -0000 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); } /*