From f5526ddb480cbc6a1d2dc2543793fcdc6ff5e210 Mon Sep 17 00:00:00 2001 From: David Greenman Date: Fri, 21 Jul 1995 10:25:13 +0000 Subject: 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. --- sys/nfsclient/nfs_node.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'sys/nfsclient') 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 @@ -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); } @@ -146,6 +168,14 @@ loop: np->n_fhsize = fhsize; *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. */ -- cgit v1.2.3