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"

Reply via email to