Author: jhb
Date: Fri Aug 20 20:58:57 2010
New Revision: 211533
URL: http://svn.freebsd.org/changeset/base/211533

Log:
  Revert 210173 as it did not properly fix the bug.  It assumed that the
  VI_LOCK() for a given vnode was used as the internal interlock for that
  vnode's v_lock lockmgr lock.  This is not the case.  Instead, add dedicated
  routines to toggle the LK_NOSHARE and LK_CANRECURSE flags.  These routines
  lock the lockmgr lock's internal interlock to synchronize the updates to
  the flags member with other threads attempting to acquire the lock.  The
  VN_LOCK_A*() macros now invoke these routines, and the softupdates code
  uses these routines to temporarly enable recursion on buffer locks.
  
  Reviewed by:  kib

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/kern/kern_lock.c
  stable/7/sys/sys/lockmgr.h
  stable/7/sys/sys/vnode.h
  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 Aug 
20 20:33:13 2010        (r211532)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Fri Aug 
20 20:58:57 2010        (r211533)
@@ -618,11 +618,8 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_bu
                vp->v_op = &zfs_fifoops;
                break;
        }
-       if (vp->v_type != VFIFO) {
-               VI_LOCK(vp);
+       if (vp->v_type != VFIFO)
                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 Aug 20 20:33:13 2010        
(r211532)
+++ stable/7/sys/fs/cd9660/cd9660_vfsops.c      Fri Aug 20 20:58:57 2010        
(r211533)
@@ -821,9 +821,7 @@ 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: stable/7/sys/fs/udf/udf_vfsops.c
==============================================================================
--- stable/7/sys/fs/udf/udf_vfsops.c    Fri Aug 20 20:33:13 2010        
(r211532)
+++ stable/7/sys/fs/udf/udf_vfsops.c    Fri Aug 20 20:58:57 2010        
(r211533)
@@ -709,11 +709,8 @@ udf_vget(struct mount *mp, ino_t ino, in
                break;
        }
 
-       if (vp->v_type != VFIFO) {
-               VI_LOCK(vp);
+       if (vp->v_type != VFIFO)
                VN_LOCK_ASHARE(vp);
-               VI_UNLOCK(vp);
-       }
 
        if (ino == udf_getid(&udfmp->root_icb))
                vp->v_vflag |= VV_ROOT;

Modified: stable/7/sys/kern/kern_lock.c
==============================================================================
--- stable/7/sys/kern/kern_lock.c       Fri Aug 20 20:33:13 2010        
(r211532)
+++ stable/7/sys/kern/kern_lock.c       Fri Aug 20 20:58:57 2010        
(r211533)
@@ -555,6 +555,40 @@ lockinit(lkp, prio, wmesg, timo, flags)
 }
 
 /*
+ * XXX: Gross hacks to manipulate external lock flags after
+ * initialization.  Used for certain vnode and buf locks.
+ */
+void
+lockallowshare(lkp)
+       struct lock *lkp;
+{
+
+       mtx_lock(lkp->lk_interlock);
+       lkp->lk_flags &= ~LK_NOSHARE;
+       mtx_unlock(lkp->lk_interlock);
+}
+
+void
+lockallowrecurse(lkp)
+       struct lock *lkp;
+{
+
+       mtx_lock(lkp->lk_interlock);
+       lkp->lk_flags |= LK_CANRECURSE;
+       mtx_unlock(lkp->lk_interlock);
+}
+
+void
+lockdisablerecurse(lkp)
+       struct lock *lkp;
+{
+
+       mtx_lock(lkp->lk_interlock);
+       lkp->lk_flags &= ~LK_CANRECURSE;
+       mtx_unlock(lkp->lk_interlock);
+}
+
+/*
  * Destroy a lock.
  */
 void

Modified: stable/7/sys/sys/lockmgr.h
==============================================================================
--- stable/7/sys/sys/lockmgr.h  Fri Aug 20 20:33:13 2010        (r211532)
+++ stable/7/sys/sys/lockmgr.h  Fri Aug 20 20:58:57 2010        (r211533)
@@ -214,6 +214,9 @@ void        lockmgr_printinfo(struct lock *);
 int    lockstatus(struct lock *, struct thread *);
 int    lockcount(struct lock *);
 int    lockwaiters(struct lock *);
+void   lockallowshare(struct lock *);
+void   lockallowrecurse(struct lock *);
+void   lockdisablerecurse(struct lock *);
 
 #define        lockmgr(lock, flags, mtx, td)                                   
\
        _lockmgr((lock), (flags), (mtx), (td), LOCK_FILE, LOCK_LINE)

Modified: stable/7/sys/sys/vnode.h
==============================================================================
--- stable/7/sys/sys/vnode.h    Fri Aug 20 20:33:13 2010        (r211532)
+++ stable/7/sys/sys/vnode.h    Fri Aug 20 20:58:57 2010        (r211533)
@@ -398,8 +398,8 @@ extern void (*lease_updatetime)(int delt
 #define        VI_UNLOCK(vp)   mtx_unlock(&(vp)->v_interlock)
 #define        VI_MTX(vp)      (&(vp)->v_interlock)
 
-#define        VN_LOCK_AREC(vp)        ((vp)->v_vnlock->lk_flags |= 
LK_CANRECURSE)
-#define        VN_LOCK_ASHARE(vp)      ((vp)->v_vnlock->lk_flags &= 
~LK_NOSHARE)
+#define        VN_LOCK_AREC(vp)        lockallowrecurse((vp)->v_vnlock)
+#define        VN_LOCK_ASHARE(vp)      lockallowshare((vp)->v_vnlock)
 
 #endif /* _KERNEL */
 

Modified: stable/7/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- stable/7/sys/ufs/ffs/ffs_softdep.c  Fri Aug 20 20:33:13 2010        
(r211532)
+++ stable/7/sys/ufs/ffs/ffs_softdep.c  Fri Aug 20 20:58:57 2010        
(r211533)
@@ -5291,9 +5291,7 @@ 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);
+       lockallowrecurse(&bp->b_lock);
        ACQUIRE_LOCK(&lk);
        /*
         * As we hold the buffer locked, none of its dependencies
@@ -5435,9 +5433,7 @@ 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);
+               lockdisablerecurse(&bp->b_lock);
                bawrite(bp);
                return (error);
        }
@@ -5449,9 +5445,7 @@ 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);
+       lockdisablerecurse(&bp->b_lock);
        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 Aug 20 20:33:13 2010        
(r211532)
+++ stable/7/sys/ufs/ffs/ffs_vfsops.c   Fri Aug 20 20:58:57 2010        
(r211533)
@@ -1519,9 +1519,7 @@ 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);
        }
 
        /*
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to