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