Author: jhb
Date: Fri Aug 20 19:46:50 2010
New Revision: 211531
URL: http://svn.freebsd.org/changeset/base/211531

Log:
  Add dedicated routines to toggle lockmgr flags such as LK_NOSHARE and
  LK_CANRECURSE after a lock is created.  Use them to implement macros that
  otherwise manipulated the flags directly.  Assert that the associated
  lockmgr lock is exclusively locked by the current thread when manipulating
  these flags to ensure the flag updates are safe.  This last change required
  some minor shuffling in a few filesystems to exclusively lock a brand new
  vnode slightly earlier.
  
  Reviewed by:  kib
  MFC after:    3 days

Modified:
  head/sys/fs/devfs/devfs_vnops.c
  head/sys/fs/nfsclient/nfs_clnode.c
  head/sys/fs/nfsclient/nfs_clport.c
  head/sys/fs/nwfs/nwfs_node.c
  head/sys/fs/pseudofs/pseudofs_vncache.c
  head/sys/fs/smbfs/smbfs_node.c
  head/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c
  head/sys/kern/kern_lock.c
  head/sys/kern/vfs_lookup.c
  head/sys/nfsclient/nfs_node.c
  head/sys/sys/lockmgr.h
  head/sys/sys/vnode.h
  head/sys/ufs/ffs/ffs_softdep.c
  head/sys/ufs/ffs/ffs_vfsops.c

Modified: head/sys/fs/devfs/devfs_vnops.c
==============================================================================
--- head/sys/fs/devfs/devfs_vnops.c     Fri Aug 20 17:52:49 2010        
(r211530)
+++ head/sys/fs/devfs/devfs_vnops.c     Fri Aug 20 19:46:50 2010        
(r211531)
@@ -412,8 +412,8 @@ devfs_allocv(struct devfs_dirent *de, st
        } else {
                vp->v_type = VBAD;
        }
-       VN_LOCK_ASHARE(vp);
        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOWITNESS);
+       VN_LOCK_ASHARE(vp);
        mtx_lock(&devfs_de_interlock);
        vp->v_data = de;
        de->de_vnode = vp;

Modified: head/sys/fs/nfsclient/nfs_clnode.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clnode.c  Fri Aug 20 17:52:49 2010        
(r211530)
+++ head/sys/fs/nfsclient/nfs_clnode.c  Fri Aug 20 19:46:50 2010        
(r211531)
@@ -140,6 +140,7 @@ ncl_nget(struct mount *mntp, u_int8_t *f
        /*
         * NFS supports recursive and shared locking.
         */
+       lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL);
        VN_LOCK_AREC(vp);
        VN_LOCK_ASHARE(vp);
        /* 
@@ -157,7 +158,6 @@ ncl_nget(struct mount *mntp, u_int8_t *f
            M_NFSFH, M_WAITOK);
        bcopy(fhp, np->n_fhp->nfh_fh, fhsize);
        np->n_fhp->nfh_len = fhsize;
-       lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL);
        error = insmntque(vp, mntp);
        if (error != 0) {
                *npp = NULL;

Modified: head/sys/fs/nfsclient/nfs_clport.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clport.c  Fri Aug 20 17:52:49 2010        
(r211530)
+++ head/sys/fs/nfsclient/nfs_clport.c  Fri Aug 20 19:46:50 2010        
(r211531)
@@ -230,9 +230,9 @@ nfscl_nget(struct mount *mntp, struct vn
        /*
         * NFS supports recursive and shared locking.
         */
+       lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL);
        VN_LOCK_AREC(vp);
        VN_LOCK_ASHARE(vp);
-       lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL);
        error = insmntque(vp, mntp);
        if (error != 0) {
                *npp = NULL;

Modified: head/sys/fs/nwfs/nwfs_node.c
==============================================================================
--- head/sys/fs/nwfs/nwfs_node.c        Fri Aug 20 17:52:49 2010        
(r211530)
+++ head/sys/fs/nwfs/nwfs_node.c        Fri Aug 20 19:46:50 2010        
(r211531)
@@ -185,7 +185,6 @@ rescan:
        if (dvp) {
                np->n_parent = VTONW(dvp)->n_fid;
        }
-       VN_LOCK_AREC(vp);
        sx_xlock(&nwhashlock);
        /*
         * Another process can create vnode while we blocked in malloc() or
@@ -202,6 +201,7 @@ rescan:
        nhpp = NWNOHASH(fid);
        LIST_INSERT_HEAD(nhpp, np, n_hash);
        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+       VN_LOCK_AREC(vp);
        sx_xunlock(&nwhashlock);
        
        ASSERT_VOP_LOCKED(dvp, "nwfs_allocvp");

Modified: head/sys/fs/pseudofs/pseudofs_vncache.c
==============================================================================
--- head/sys/fs/pseudofs/pseudofs_vncache.c     Fri Aug 20 17:52:49 2010        
(r211530)
+++ head/sys/fs/pseudofs/pseudofs_vncache.c     Fri Aug 20 19:46:50 2010        
(r211531)
@@ -189,8 +189,8 @@ retry:
        if ((pn->pn_flags & PFS_PROCDEP) != 0)
                (*vpp)->v_vflag |= VV_PROCDEP;
        pvd->pvd_vnode = *vpp;
-       VN_LOCK_AREC(*vpp);
        vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
+       VN_LOCK_AREC(*vpp);
        error = insmntque(*vpp, mp);
        if (error != 0) {
                free(pvd, M_PFSVNCACHE);

Modified: head/sys/fs/smbfs/smbfs_node.c
==============================================================================
--- head/sys/fs/smbfs/smbfs_node.c      Fri Aug 20 17:52:49 2010        
(r211530)
+++ head/sys/fs/smbfs/smbfs_node.c      Fri Aug 20 19:46:50 2010        
(r211531)
@@ -253,8 +253,8 @@ loop:
        } else if (vp->v_type == VREG)
                SMBERROR("new vnode '%s' born without parent ?\n", np->n_name);
 
-       VN_LOCK_AREC(vp);
        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+       VN_LOCK_AREC(vp);
 
        smbfs_hash_lock(smp);
        LIST_FOREACH(np2, nhpp, n_hash) {

Modified: head/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c
==============================================================================
--- head/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c      Fri Aug 20 17:52:49 
2010        (r211530)
+++ head/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c      Fri Aug 20 19:46:50 
2010        (r211531)
@@ -389,8 +389,8 @@ xfs_vn_allocate(xfs_mount_t *mp, xfs_ino
                return (error);
        }
 
-       VN_LOCK_AREC(vp);
        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+       VN_LOCK_AREC(vp);
        error = insmntque(vp, XVFSTOMNT(XFS_MTOVFS(mp)));
        if (error != 0) {
                kmem_free(vdata, sizeof(*vdata));

Modified: head/sys/kern/kern_lock.c
==============================================================================
--- head/sys/kern/kern_lock.c   Fri Aug 20 17:52:49 2010        (r211530)
+++ head/sys/kern/kern_lock.c   Fri Aug 20 19:46:50 2010        (r211531)
@@ -396,6 +396,34 @@ lockinit(struct lock *lk, int pri, const
        STACK_ZERO(lk);
 }
 
+/*
+ * XXX: Gross hacks to manipulate external lock flags after
+ * initialization.  Used for certain vnode and buf locks.
+ */
+void
+lockallowshare(struct lock *lk)
+{
+
+       lockmgr_assert(lk, KA_XLOCKED);
+       lk->lock_object.lo_flags &= ~LK_NOSHARE;
+}
+
+void
+lockallowrecurse(struct lock *lk)
+{
+
+       lockmgr_assert(lk, KA_XLOCKED);
+       lk->lock_object.lo_flags |= LO_RECURSABLE;
+}
+
+void
+lockdisablerecurse(struct lock *lk)
+{
+
+       lockmgr_assert(lk, KA_XLOCKED);
+       lk->lock_object.lo_flags &= ~LO_RECURSABLE;
+}
+
 void
 lockdestroy(struct lock *lk)
 {

Modified: head/sys/kern/vfs_lookup.c
==============================================================================
--- head/sys/kern/vfs_lookup.c  Fri Aug 20 17:52:49 2010        (r211530)
+++ head/sys/kern/vfs_lookup.c  Fri Aug 20 19:46:50 2010        (r211531)
@@ -84,14 +84,13 @@ static struct vnode *vp_crossmp;
 static void
 nameiinit(void *dummy __unused)
 {
-       int error;
 
        namei_zone = uma_zcreate("NAMEI", MAXPATHLEN, NULL, NULL, NULL, NULL,
            UMA_ALIGN_PTR, 0);
-       error = getnewvnode("crossmp", NULL, &dead_vnodeops, &vp_crossmp);
-       if (error != 0)
-               panic("nameiinit: getnewvnode");
+       getnewvnode("crossmp", NULL, &dead_vnodeops, &vp_crossmp);
+       vn_lock(vp_crossmp, LK_EXCLUSIVE);
        VN_LOCK_ASHARE(vp_crossmp);
+       VOP_UNLOCK(vp_crossmp, 0);
 }
 SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL);
 

Modified: head/sys/nfsclient/nfs_node.c
==============================================================================
--- head/sys/nfsclient/nfs_node.c       Fri Aug 20 17:52:49 2010        
(r211530)
+++ head/sys/nfsclient/nfs_node.c       Fri Aug 20 19:46:50 2010        
(r211531)
@@ -150,6 +150,7 @@ nfs_nget(struct mount *mntp, nfsfh_t *fh
        /*
         * NFS supports recursive and shared locking.
         */
+       lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL);
        VN_LOCK_AREC(vp);
        VN_LOCK_ASHARE(vp);
        if (fhsize > NFS_SMALLFH) {
@@ -158,7 +159,6 @@ nfs_nget(struct mount *mntp, nfsfh_t *fh
                np->n_fhp = &np->n_fh;
        bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize);
        np->n_fhsize = fhsize;
-       lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL);
        error = insmntque(vp, mntp);
        if (error != 0) {
                *npp = NULL;

Modified: head/sys/sys/lockmgr.h
==============================================================================
--- head/sys/sys/lockmgr.h      Fri Aug 20 17:52:49 2010        (r211530)
+++ head/sys/sys/lockmgr.h      Fri Aug 20 19:46:50 2010        (r211531)
@@ -73,7 +73,10 @@ void  _lockmgr_assert(struct lock *lk, i
 #endif
 void    _lockmgr_disown(struct lock *lk, const char *file, int line);
 
+void    lockallowrecurse(struct lock *lk);
+void    lockallowshare(struct lock *lk);
 void    lockdestroy(struct lock *lk);
+void    lockdisablerecurse(struct lock *lk);
 void    lockinit(struct lock *lk, int prio, const char *wmesg, int timo,
            int flags);
 #ifdef DDB

Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h        Fri Aug 20 17:52:49 2010        (r211530)
+++ head/sys/sys/vnode.h        Fri Aug 20 19:46:50 2010        (r211531)
@@ -419,10 +419,8 @@ extern     struct vattr va_null;           /* predefi
 #define        VI_UNLOCK(vp)   mtx_unlock(&(vp)->v_interlock)
 #define        VI_MTX(vp)      (&(vp)->v_interlock)
 
-#define        VN_LOCK_AREC(vp)                                                
\
-       ((vp)->v_vnlock->lock_object.lo_flags |= LO_RECURSABLE)
-#define        VN_LOCK_ASHARE(vp)                                              
\
-       ((vp)->v_vnlock->lock_object.lo_flags &= ~LK_NOSHARE)
+#define        VN_LOCK_AREC(vp)        lockallowrecurse((vp)->v_vnlock)
+#define        VN_LOCK_ASHARE(vp)      lockallowshare((vp)->v_vnlock)
 
 #endif /* _KERNEL */
 

Modified: head/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- head/sys/ufs/ffs/ffs_softdep.c      Fri Aug 20 17:52:49 2010        
(r211530)
+++ head/sys/ufs/ffs/ffs_softdep.c      Fri Aug 20 19:46:50 2010        
(r211531)
@@ -904,8 +904,8 @@ MTX_SYSINIT(softdep_lock, &lk, "Softdep 
 #define ACQUIRE_LOCK(lk)               mtx_lock(lk)
 #define FREE_LOCK(lk)                  mtx_unlock(lk)
 
-#define        BUF_AREC(bp)    ((bp)->b_lock.lock_object.lo_flags |= 
LO_RECURSABLE)
-#define        BUF_NOREC(bp)   ((bp)->b_lock.lock_object.lo_flags &= 
~LO_RECURSABLE)
+#define        BUF_AREC(bp)                    lockallowrecurse(&(bp)->b_lock)
+#define        BUF_NOREC(bp)                   
lockdisablerecurse(&(bp)->b_lock)
 
 /*
  * Worklist queue management.

Modified: head/sys/ufs/ffs/ffs_vfsops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vfsops.c       Fri Aug 20 17:52:49 2010        
(r211530)
+++ head/sys/ufs/ffs/ffs_vfsops.c       Fri Aug 20 19:46:50 2010        
(r211531)
@@ -1501,6 +1501,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags
        /*
         * FFS supports recursive locking.
         */
+       lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
        VN_LOCK_AREC(vp);
        vp->v_data = ip;
        vp->v_bufobj.bo_bsize = fs->fs_bsize;
@@ -1518,7 +1519,6 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags
        }
 #endif
 
-       lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
        if (ffs_flags & FFSV_FORCEINSMQ)
                vp->v_vflag |= VV_FORCEINSMQ;
        error = insmntque(vp, mp);
_______________________________________________
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