summaryrefslogtreecommitdiffstats
path: root/sys/nfsclient
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1995-07-21 10:25:13 +0000
committerdg <dg@FreeBSD.org>1995-07-21 10:25:13 +0000
commita7d187059955345b521e0b17b3462d4cfacf5e6b (patch)
tree5e3c6b5369a3e9b62295fd49476177eec203994b /sys/nfsclient
parentdc33f04058c2644675b3830c7df8a5942800a681 (diff)
downloadFreeBSD-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.c32
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);
OpenPOWER on IntegriCloud