diff options
author | dg <dg@FreeBSD.org> | 1995-07-21 10:25:13 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1995-07-21 10:25:13 +0000 |
commit | a7d187059955345b521e0b17b3462d4cfacf5e6b (patch) | |
tree | 5e3c6b5369a3e9b62295fd49476177eec203994b /sys/nfsclient | |
parent | dc33f04058c2644675b3830c7df8a5942800a681 (diff) | |
download | FreeBSD-src-a7d187059955345b521e0b17b3462d4cfacf5e6b.zip FreeBSD-src-a7d187059955345b521e0b17b3462d4cfacf5e6b.tar.gz |
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.
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 c002cea..ceaec31 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); |