diff options
author | semenu <semenu@FreeBSD.org> | 2002-06-13 18:25:06 +0000 |
---|---|---|
committer | semenu <semenu@FreeBSD.org> | 2002-06-13 18:25:06 +0000 |
commit | 7e3005a305921f4ef318191154628c2723c3c2bf (patch) | |
tree | 00f39a8efe57dd5371cd3f460bc978cc373ac8c6 /sys/fs | |
parent | 7baa028f375f33f5042fc2e26feba46a7aa2115f (diff) | |
download | FreeBSD-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.h | 2 | ||||
-rw-r--r-- | sys/fs/nullfs/null_subr.c | 24 | ||||
-rw-r--r-- | sys/fs/nullfs/null_vnops.c | 19 |
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); } |