Author: jhb Date: Fri Jul 16 19:20:20 2010 New Revision: 210171 URL: http://svn.freebsd.org/changeset/base/210171
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 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. MFC after: 3 days Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c head/sys/fs/cd9660/cd9660_vfsops.c head/sys/fs/udf/udf_vfsops.c head/sys/ufs/ffs/ffs_vfsops.c Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Fri Jul 16 18:57:45 2010 (r210170) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Fri Jul 16 19:20:20 2010 (r210171) @@ -566,8 +566,11 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_bu } 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: head/sys/fs/cd9660/cd9660_vfsops.c ============================================================================== --- head/sys/fs/cd9660/cd9660_vfsops.c Fri Jul 16 18:57:45 2010 (r210170) +++ head/sys/fs/cd9660/cd9660_vfsops.c Fri Jul 16 19:20:20 2010 (r210171) @@ -814,7 +814,9 @@ cd9660_vget_internal(mp, ino, flags, vpp vp->v_op = &cd9660_fifoops; break; default: + VI_LOCK(vp); VN_LOCK_ASHARE(vp); + VI_UNLOCK(vp); break; } Modified: head/sys/fs/udf/udf_vfsops.c ============================================================================== --- head/sys/fs/udf/udf_vfsops.c Fri Jul 16 18:57:45 2010 (r210170) +++ head/sys/fs/udf/udf_vfsops.c Fri Jul 16 19:20:20 2010 (r210171) @@ -710,8 +710,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: head/sys/ufs/ffs/ffs_vfsops.c ============================================================================== --- head/sys/ufs/ffs/ffs_vfsops.c Fri Jul 16 18:57:45 2010 (r210170) +++ head/sys/ufs/ffs/ffs_vfsops.c Fri Jul 16 19:20:20 2010 (r210171) @@ -1577,7 +1577,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); } /* _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"