static vm_zone_t nfsnode_zone;
static LIST_HEAD(nfsnodehashhead, nfsnode) *nfsnodehashtbl;
static u_long nfsnodehash;
+static lwkt_token nfsnhash_token = LWKT_TOKEN_MP_INITIALIZER(nfsnhash_token);
+static struct lock nfsnhash_lock;
#define TRUE 1
#define FALSE 0
{
nfsnode_zone = zinit("NFSNODE", sizeof(struct nfsnode), 0, 0, 1);
nfsnodehashtbl = hashinit(desiredvnodes, M_NFSHASH, &nfsnodehash);
+ lockinit(&nfsnhash_lock, "nfsnht", 0, 0);
}
/*
* In all cases, a pointer to a
* nfsnode structure is returned.
*/
-static int nfs_node_hash_lock;
int
nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp)
else
lkflags = 0;
+ lwkt_gettoken(&nfsnhash_token);
+
retry:
nhpp = NFSNOHASH(fnv_32_buf(fhp->fh_bytes, fhsize, FNV1_32_INIT));
loop:
goto loop;
}
*npp = np;
+ lwkt_reltoken(&nfsnhash_token);
return(0);
}
+
/*
* Obtain a lock to prevent a race condition if the getnewvnode()
* or MALLOC() below happens to block.
*/
- if (nfs_node_hash_lock) {
- while (nfs_node_hash_lock) {
- nfs_node_hash_lock = -1;
- tsleep(&nfs_node_hash_lock, 0, "nfsngt", 0);
- }
+ if (lockmgr(&nfsnhash_lock, LK_EXCLUSIVE | LK_SLEEPFAIL))
goto loop;
- }
- nfs_node_hash_lock = 1;
/*
* Allocate before getnewvnode since doing so afterward
error = getnewvnode(VT_NFS, mntp, &nvp, 0, 0);
if (error) {
- if (nfs_node_hash_lock < 0)
- wakeup(&nfs_node_hash_lock);
- nfs_node_hash_lock = 0;
+ lockmgr(&nfsnhash_lock, LK_RELEASE);
*npp = 0;
zfree(nfsnode_zone, np);
+ lwkt_reltoken(&nfsnhash_token);
return (error);
}
vp = nvp;
bcmp((caddr_t)fhp, (caddr_t)np2->n_fhp, fhsize))
continue;
vx_put(vp);
- if (nfs_node_hash_lock < 0)
- wakeup(&nfs_node_hash_lock);
- nfs_node_hash_lock = 0;
+ lockmgr(&nfsnhash_lock, LK_RELEASE);
zfree(nfsnode_zone, np);
goto retry;
}
* nvp is locked & refd so effectively so is np.
*/
*npp = np;
- if (nfs_node_hash_lock < 0)
- wakeup(&nfs_node_hash_lock);
- nfs_node_hash_lock = 0;
+ lockmgr(&nfsnhash_lock, LK_RELEASE);
+ lwkt_reltoken(&nfsnhash_token);
return (0);
}
lkflags = 0;
vp = NULL;
*npp = NULL;
+
+ lwkt_gettoken(&nfsnhash_token);
+
retry:
nhpp = NFSNOHASH(fnv_32_buf(fhp->fh_bytes, fhsize, FNV1_32_INIT));
loop:
goto loop;
}
*npp = np;
+ lwkt_reltoken(&nfsnhash_token);
return(0);
}
* Obtain a lock to prevent a race condition if the getnewvnode()
* or MALLOC() below happens to block.
*/
- if (nfs_node_hash_lock) {
- while (nfs_node_hash_lock) {
- nfs_node_hash_lock = -1;
- tsleep(&nfs_node_hash_lock, 0, "nfsngt", 0);
- }
+ if (lockmgr(&nfsnhash_lock, LK_EXCLUSIVE | LK_SLEEPFAIL))
goto loop;
- }
- nfs_node_hash_lock = 1;
/*
* Entry not found, allocate a new entry.
error = getnewvnode(VT_NFS, mntp, &nvp, 0, 0);
if (error) {
- if (nfs_node_hash_lock < 0)
- wakeup(&nfs_node_hash_lock);
- nfs_node_hash_lock = 0;
+ lockmgr(&nfsnhash_lock, LK_RELEASE);
zfree(nfsnode_zone, np);
+ lwkt_reltoken(&nfsnhash_token);
return (error);
}
vp = nvp;
continue;
}
vx_put(vp);
- if (nfs_node_hash_lock < 0)
- wakeup(&nfs_node_hash_lock);
- nfs_node_hash_lock = 0;
+ lockmgr(&nfsnhash_lock, LK_RELEASE);
zfree(nfsnode_zone, np);
goto retry;
}
*/
*npp = np;
error = 0;
- if (nfs_node_hash_lock < 0)
- wakeup(&nfs_node_hash_lock);
- nfs_node_hash_lock = 0;
+ lockmgr(&nfsnhash_lock, LK_RELEASE);
fail:
+ lwkt_reltoken(&nfsnhash_token);
return (error);
}
if (prtactive && vp->v_sysref.refcnt > 1)
vprint("nfs_reclaim: pushing active", vp);
- lwkt_gettoken(&nmp->nm_token);
+ /*
+ * Remove from hash table
+ */
+ lwkt_gettoken(&nfsnhash_token);
if (np->n_hash.le_prev != NULL)
LIST_REMOVE(np, n_hash);
+ lwkt_reltoken(&nfsnhash_token);
/*
* Free up any directory cookie structures and
* large file handle structures that might be associated with
* this nfs node.
*/
+ lwkt_gettoken(&nmp->nm_token);
if (vp->v_type == VDIR) {
dp = np->n_cookies.lh_first;
while (dp) {