summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/nfs/nfs_node.c38
-rw-r--r--sys/sys/vnode.h5
2 files changed, 35 insertions, 8 deletions
diff --git a/sys/nfs/nfs_node.c b/sys/nfs/nfs_node.c
index 94e7fd6640d..44efb9ed504 100644
--- a/sys/nfs/nfs_node.c
+++ b/sys/nfs/nfs_node.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_node.c,v 1.50 2009/12/15 17:04:00 beck Exp $ */
+/* $OpenBSD: nfs_node.c,v 1.51 2009/12/17 16:30:47 beck Exp $ */
/* $NetBSD: nfs_node.c,v 1.16 1996/02/18 11:53:42 fvdl Exp $ */
/*
@@ -115,15 +115,17 @@ loop:
*/
rw_exit_write(&nfs_hashlock);
error = getnewvnode(VT_NFS, mnt, nfsv2_vnodeop_p, &nvp);
+ /* note that we don't have this vnode set up completely yet */
rw_enter_write(&nfs_hashlock);
if (error) {
*npp = NULL;
rw_exit_write(&nfs_hashlock);
return (error);
}
-
+ nvp->v_flag |= VLARVAL;
np = RB_FIND(nfs_nodetree, &nmp->nm_ntree, &find);
if (np != NULL) {
+ vgone(nvp);
rw_exit_write(&nfs_hashlock);
goto loop;
}
@@ -131,6 +133,8 @@ loop:
vp = nvp;
np = pool_get(&nfs_node_pool, PR_WAITOK | PR_ZERO);
vp->v_data = np;
+ /* we now have an nfsnode on this vnode */
+ vp->v_flag &= ~VLARVAL;
np->n_vnode = vp;
rw_init(&np->n_commitlock, "nfs_commitlk");
@@ -161,14 +165,25 @@ int
nfs_inactive(void *v)
{
struct vop_inactive_args *ap = v;
- struct nfsnode *np = VTONFS(ap->a_vp);
+ struct nfsnode *np;
struct sillyrename *sp;
#ifdef DIAGNOSTIC
if (prtactive && ap->a_vp->v_usecount != 0)
vprint("nfs_inactive: pushing active", ap->a_vp);
#endif
-
+ if (ap->a_vp->v_flag & VLARVAL)
+ /*
+ * vnode was incompletely set up, just return
+ * as we are throwing it away.
+ */
+ return(0);
+#ifdef DIAGNOSTIC
+ if (ap->a_vp->v_data == NULL)
+ panic("NULL v_data (no nfsnode set up?) in vnode %p\n",
+ ap->a_vp);
+#endif
+ np = VTONFS(ap->a_vp);
if (ap->a_vp->v_type != VDIR) {
sp = np->n_sillyrename;
np->n_sillyrename = NULL;
@@ -198,14 +213,25 @@ nfs_reclaim(void *v)
{
struct vop_reclaim_args *ap = v;
struct vnode *vp = ap->a_vp;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
+ struct nfsmount *nmp;
struct nfsnode *np = VTONFS(vp);
#ifdef DIAGNOSTIC
if (prtactive && vp->v_usecount != 0)
vprint("nfs_reclaim: pushing active", vp);
#endif
-
+ if (ap->a_vp->v_flag & VLARVAL)
+ /*
+ * vnode was incompletely set up, just return
+ * as we are throwing it away.
+ */
+ return(0);
+#ifdef DIAGNOSTIC
+ if (ap->a_vp->v_data == NULL)
+ panic("NULL v_data (no nfsnode set up?) in vnode %p\n",
+ ap->a_vp);
+#endif
+ nmp = VFSTONFS(vp->v_mount);
rw_enter_write(&nfs_hashlock);
RB_REMOVE(nfs_nodetree, &nmp->nm_ntree, np);
rw_exit_write(&nfs_hashlock);
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 019e28a251a..76eea0e99d8 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnode.h,v 1.103 2009/08/12 16:42:24 beck Exp $ */
+/* $OpenBSD: vnode.h,v 1.104 2009/12/17 16:30:45 beck Exp $ */
/* $NetBSD: vnode.h,v 1.38 1996/02/29 20:59:05 cgd Exp $ */
/*
@@ -136,10 +136,11 @@ struct vnode {
#define VXWANT 0x0200 /* process is waiting for vnode */
#define VCLONED 0x0400 /* vnode was cloned */
#define VALIASED 0x0800 /* vnode has an alias */
+#define VLARVAL 0x1000 /* vnode data not yet set up by higher level */
#define VLOCKSWORK 0x4000 /* FS supports locking discipline */
#define VCLONE 0x8000 /* vnode is a clone */
#define VBITS "\010\001ROOT\002TEXT\003SYSTEM\004ISTTY\010XLOCK" \
- "\011XWANT\013ALIASED\016LOCKSWORK\017CLONE"
+ "\011XWANT\013ALIASED\014LARVAL\016LOCKSWORK\017CLONE"
/*
* (v_bioflag) Flags that may be manipulated by interrupt handlers