diff options
author | David Greenman <dg@FreeBSD.org> | 1995-07-21 10:25:13 +0000 |
---|---|---|
committer | David Greenman <dg@FreeBSD.org> | 1995-07-21 10:25:13 +0000 |
commit | f5526ddb480cbc6a1d2dc2543793fcdc6ff5e210 (patch) | |
tree | 5e3c6b5369a3e9b62295fd49476177eec203994b /sys/nfsclient | |
parent | 44918dfed789875d7b2081396a89f2d1bde755f3 (diff) | |
download | src-f5526ddb480cbc6a1d2dc2543793fcdc6ff5e210.tar.gz src-f5526ddb480cbc6a1d2dc2543793fcdc6ff5e210.zip |
Implemented an nfs_node hash list lock, similar to what was implemented
in ffs_vget(), and for the same reason: to prevent a race condition that
results in duplicate vnodes/NFSnodes being allocated.
Notes
Notes:
svn path=/head/; revision=9604
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/nfs_node.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c index c002cea01bd5..ceaec31d5b78 100644 --- a/sys/nfsclient/nfs_node.c +++ b/sys/nfsclient/nfs_node.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_node.c 8.2 (Berkeley) 12/30/93 - * $Id: nfs_node.c,v 1.8 1995/03/16 18:15:36 bde Exp $ + * $Id: nfs_node.c,v 1.9 1995/06/27 11:06:35 dfr Exp $ */ #include <sys/param.h> @@ -99,6 +99,8 @@ nfs_hash(fhp, fhsize) * In all cases, a pointer to a * nfsnode structure is returned. */ +int nfs_node_hash_lock; + int nfs_nget(mntp, fhp, fhsize, npp) struct mount *mntp; @@ -124,8 +126,28 @@ loop: *npp = np; return(0); } + /* + * Obtain a lock to prevent a race condition if the getnewvnode + * or malloc below happen to block. + */ + if (nfs_node_hash_lock) { + while (nfs_node_hash_lock) { + nfs_node_hash_lock = -1; + tsleep(&nfs_node_hash_lock, PVM, "ffsvgt", 0); + } + goto loop; + } + nfs_node_hash_lock = 1; + error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &nvp); if (error) { + /* + * Wakeup anyone blocked on our lock. + */ + if (nfs_node_hash_lock < 0) { + wakeup(&nfs_node_hash_lock); + } + nfs_node_hash_lock = 0; *npp = 0; return (error); } @@ -147,6 +169,14 @@ loop: *npp = np; /* + * Wakeup anyone blocked on our lock + */ + if (nfs_node_hash_lock < 0) { + wakeup(&nfs_node_hash_lock); + } + nfs_node_hash_lock = 0; + + /* * Lock the new nfsnode. */ VOP_LOCK(vp); |