Replace lockmgr lock protecting nwfs vnode hash table with an sx lock.

MFC after:	1 month
This commit is contained in:
Robert Watson 2008-03-02 19:02:30 +00:00
parent 7947229ff6
commit 970a2d8770

View File

@ -40,6 +40,7 @@
#include <sys/mutex.h> #include <sys/mutex.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/sx.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/vnode.h> #include <sys/vnode.h>
@ -62,7 +63,7 @@
static LIST_HEAD(nwnode_hash_head,nwnode) *nwhashtbl; static LIST_HEAD(nwnode_hash_head,nwnode) *nwhashtbl;
static u_long nwnodehash; static u_long nwnodehash;
static struct lock nwhashlock; static struct sx nwhashlock;
static MALLOC_DEFINE(M_NWNODE, "nwfs_node", "NWFS vnode private part"); static MALLOC_DEFINE(M_NWNODE, "nwfs_node", "NWFS vnode private part");
static MALLOC_DEFINE(M_NWFSHASH, "nwfs_hash", "NWFS has table"); static MALLOC_DEFINE(M_NWFSHASH, "nwfs_hash", "NWFS has table");
@ -77,12 +78,12 @@ SYSCTL_PROC(_vfs_nwfs, OID_AUTO, vnprint, CTLFLAG_WR|CTLTYPE_OPAQUE,
void void
nwfs_hash_init(void) { nwfs_hash_init(void) {
nwhashtbl = hashinit(desiredvnodes, M_NWFSHASH, &nwnodehash); nwhashtbl = hashinit(desiredvnodes, M_NWFSHASH, &nwnodehash);
lockinit(&nwhashlock, PVFS, "nwfshl", 0, 0); sx_init(&nwhashlock, "nwfshl");
} }
void void
nwfs_hash_free(void) { nwfs_hash_free(void) {
lockdestroy(&nwhashlock); sx_destroy(&nwhashlock);
free(nwhashtbl, M_NWFSHASH); free(nwhashtbl, M_NWFSHASH);
} }
@ -118,6 +119,8 @@ nwfs_hashlookup(struct nwmount *nmp, ncpfid fid, struct nwnode **npp)
struct nwnode *np; struct nwnode *np;
struct nwnode_hash_head *nhpp; struct nwnode_hash_head *nhpp;
sx_assert(&nwhashlock, SA_XLOCKED);
nhpp = NWNOHASH(fid); nhpp = NWNOHASH(fid);
LIST_FOREACH(np, nhpp, n_hash) { LIST_FOREACH(np, nhpp, n_hash) {
if (nmp != np->n_mount || !NWCMPF(&fid, &np->n_fid)) if (nmp != np->n_mount || !NWCMPF(&fid, &np->n_fid))
@ -144,12 +147,12 @@ nwfs_allocvp(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
int error; int error;
loop: loop:
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL); sx_xlock(&nwhashlock);
rescan: rescan:
if (nwfs_hashlookup(nmp, fid, &np) == 0) { if (nwfs_hashlookup(nmp, fid, &np) == 0) {
vp = NWTOV(np); vp = NWTOV(np);
mtx_lock(&vp->v_interlock); mtx_lock(&vp->v_interlock);
lockmgr(&nwhashlock, LK_RELEASE, NULL); sx_xunlock(&nwhashlock);
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, curthread)) if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, curthread))
goto loop; goto loop;
if (fap) if (fap)
@ -157,7 +160,7 @@ nwfs_allocvp(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
*vpp = vp; *vpp = vp;
return(0); return(0);
} }
lockmgr(&nwhashlock, LK_RELEASE, NULL); sx_xunlock(&nwhashlock);
if (fap == NULL || ((fap->attributes & aDIR) == 0 && dvp == NULL)) if (fap == NULL || ((fap->attributes & aDIR) == 0 && dvp == NULL))
panic("nwfs_allocvp: fap = %p, dvp = %p\n", fap, dvp); panic("nwfs_allocvp: fap = %p, dvp = %p\n", fap, dvp);
@ -189,7 +192,7 @@ nwfs_allocvp(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
np->n_parent = VTONW(dvp)->n_fid; np->n_parent = VTONW(dvp)->n_fid;
} }
VN_LOCK_AREC(vp); VN_LOCK_AREC(vp);
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL); sx_xlock(&nwhashlock);
/* /*
* Another process can create vnode while we blocked in malloc() or * Another process can create vnode while we blocked in malloc() or
* getnewvnode(). Rescan list again. * getnewvnode(). Rescan list again.
@ -205,7 +208,7 @@ nwfs_allocvp(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
nhpp = NWNOHASH(fid); nhpp = NWNOHASH(fid);
LIST_INSERT_HEAD(nhpp, np, n_hash); LIST_INSERT_HEAD(nhpp, np, n_hash);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
lockmgr(&nwhashlock, LK_RELEASE, NULL); sx_xunlock(&nwhashlock);
ASSERT_VOP_LOCKED(dvp, "nwfs_allocvp"); ASSERT_VOP_LOCKED(dvp, "nwfs_allocvp");
if (vp->v_type == VDIR && dvp && (dvp->v_vflag & VV_ROOT) == 0) { if (vp->v_type == VDIR && dvp && (dvp->v_vflag & VV_ROOT) == 0) {
@ -238,9 +241,9 @@ nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct thread *td,
{ {
int error; int error;
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL); sx_xlock(&nwhashlock);
error = nwfs_hashlookup(nmp, fid, npp); error = nwfs_hashlookup(nmp, fid, npp);
lockmgr(&nwhashlock, LK_RELEASE, NULL); sx_xunlock(&nwhashlock);
return error; return error;
} }
@ -273,9 +276,9 @@ nwfs_reclaim(ap)
NCPVNDEBUG("%s: has no parent ?\n",np->n_name); NCPVNDEBUG("%s: has no parent ?\n",np->n_name);
} }
} }
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL); sx_xlock(&nwhashlock);
LIST_REMOVE(np, n_hash); LIST_REMOVE(np, n_hash);
lockmgr(&nwhashlock, LK_RELEASE, NULL); sx_xunlock(&nwhashlock);
if (nmp->n_root == np) { if (nmp->n_root == np) {
nmp->n_root = NULL; nmp->n_root = NULL;
} }