svn commit: r211531 - in head/sys: fs/devfs fs/nfsclient fs/nwfs fs/pseudofs fs/smbfs gnu/fs/xfs/FreeBSD kern nfsclient sys ufs/ffs

John Baldwin jhb at FreeBSD.org
Fri Aug 20 19:46:51 UTC 2010


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);


More information about the svn-src-head mailing list