From owner-svn-src-all@FreeBSD.ORG Fri Aug 20 19:46:51 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 10E761065697; Fri, 20 Aug 2010 19:46:51 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id F266A8FC20; Fri, 20 Aug 2010 19:46:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7KJkoFw046363; Fri, 20 Aug 2010 19:46:50 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7KJkoWU046348; Fri, 20 Aug 2010 19:46:50 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201008201946.o7KJkoWU046348@svn.freebsd.org> From: John Baldwin Date: Fri, 20 Aug 2010 19:46:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: 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 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Aug 2010 19:46:51 -0000 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);