summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorsemenu <semenu@FreeBSD.org>2002-06-13 18:25:06 +0000
committersemenu <semenu@FreeBSD.org>2002-06-13 18:25:06 +0000
commit7e3005a305921f4ef318191154628c2723c3c2bf (patch)
tree00f39a8efe57dd5371cd3f460bc978cc373ac8c6 /sys/fs
parent7baa028f375f33f5042fc2e26feba46a7aa2115f (diff)
downloadFreeBSD-src-7e3005a305921f4ef318191154628c2723c3c2bf.zip
FreeBSD-src-7e3005a305921f4ef318191154628c2723c3c2bf.tar.gz
Fix the "error" path (when dropping not fully initialized vnode).
Also move hash operations out of null_vnops.c and explicitly initialize v_lock in null_node_alloc (to set wmesg). Reviewed by: bp MFC after: 2 weeks
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/nullfs/null.h2
-rw-r--r--sys/fs/nullfs/null_subr.c24
-rw-r--r--sys/fs/nullfs/null_vnops.c19
3 files changed, 26 insertions, 19 deletions
diff --git a/sys/fs/nullfs/null.h b/sys/fs/nullfs/null.h
index 8d02b44..718deaa 100644
--- a/sys/fs/nullfs/null.h
+++ b/sys/fs/nullfs/null.h
@@ -60,6 +60,7 @@ struct null_node {
int nullfs_init(struct vfsconf *vfsp);
int nullfs_uninit(struct vfsconf *vfsp);
int null_node_create(struct mount *mp, struct vnode *target, struct vnode **vpp);
+void null_hashrem(struct null_node *xp);
int null_bypass(struct vop_generic_args *ap);
#ifdef DIAGNOSTIC
@@ -70,7 +71,6 @@ struct vnode *null_checkvp(struct vnode *vp, char *fil, int lno);
#endif
extern vop_t **null_vnodeop_p;
-extern struct lock null_hashlock;
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_NULLFSNODE);
diff --git a/sys/fs/nullfs/null_subr.c b/sys/fs/nullfs/null_subr.c
index add959e..5e1d7b3 100644
--- a/sys/fs/nullfs/null_subr.c
+++ b/sys/fs/nullfs/null_subr.c
@@ -183,10 +183,15 @@ null_node_alloc(mp, lowervp, vpp)
}
vp = *vpp;
- vp->v_type = lowervp->v_type;
xp->null_vnode = vp;
- vp->v_data = xp;
xp->null_lowervp = lowervp;
+
+ vp->v_type = lowervp->v_type;
+ vp->v_data = xp;
+
+ /* Though v_lock is inited by getnewvnode(), we want our own wmesg */
+ lockinit(&vp->v_lock, PVFS, "nunode", VLKTIMEOUT, LK_NOPAUSE);
+
/*
* Before we insert our new node onto the hash chains,
* check to see if someone else has beaten us to it.
@@ -194,9 +199,7 @@ null_node_alloc(mp, lowervp, vpp)
*/
othervp = null_node_find(mp, lowervp);
if (othervp) {
- vp->v_data = NULL;
- FREE(xp, M_NULLFSNODE);
- vp->v_type = VBAD; /* node is discarded */
+ xp->null_lowervp = NULL;
vrele(vp);
*vpp = othervp;
return 0;
@@ -286,6 +289,17 @@ null_node_create(mp, lowervp, newvpp)
return (0);
}
+void
+null_hashrem(xp)
+ struct null_node *xp;
+{
+ struct thread *td = curthread; /* XXX */
+
+ lockmgr(&null_hashlock, LK_EXCLUSIVE, NULL, td);
+ LIST_REMOVE(xp, null_hash);
+ lockmgr(&null_hashlock, LK_RELEASE, NULL, td);
+}
+
#ifdef DIAGNOSTIC
#include "opt_ddb.h"
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index 1229e59..f3201e2 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -739,26 +739,19 @@ null_reclaim(ap)
struct thread *a_td;
} */ *ap;
{
- struct thread *td = ap->a_td;
struct vnode *vp = ap->a_vp;
struct null_node *xp = VTONULL(vp);
struct vnode *lowervp = xp->null_lowervp;
- void *vdata;
- lockmgr(&null_hashlock, LK_EXCLUSIVE, NULL, td);
- LIST_REMOVE(xp, null_hash);
- lockmgr(&null_hashlock, LK_RELEASE, NULL, td);
+ if (lowervp) {
+ null_hashrem(xp);
- /*
- * Now it is safe to drop references to the lower vnode.
- * VOP_INACTIVE() will be called by vrele() if necessary.
- */
- vrele(lowervp);
- vrele(lowervp);
+ vrele(lowervp);
+ vrele(lowervp);
+ }
- vdata = vp->v_data;
vp->v_data = NULL;
- FREE(vdata, M_NULLFSNODE);
+ FREE(xp, M_NULLFSNODE);
return (0);
}
OpenPOWER on IntegriCloud