diff options
author | kib <kib@FreeBSD.org> | 2009-05-31 14:54:20 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-05-31 14:54:20 +0000 |
commit | 0e1f2d3b3e4e791ad8dc69b5d3edfdbc1eca9771 (patch) | |
tree | a410300811ee6eb4b37ec65b17adbd6d2d8ba53f /sys/fs/nullfs/null_subr.c | |
parent | d52fd86523b726aba4b8411ebc8a3aae736ca352 (diff) | |
download | FreeBSD-src-0e1f2d3b3e4e791ad8dc69b5d3edfdbc1eca9771.zip FreeBSD-src-0e1f2d3b3e4e791ad8dc69b5d3edfdbc1eca9771.tar.gz |
Do not drop vnode interlock in null_checkvp(). null_lock() verifies that
v_data is not-null before calling NULLVPTOLOWERVP(), and dropping the
interlock allows for reclaim to clean v_data and free the memory.
While there, remove unneeded semicolons and convert the infinite loops
to panics. I have a will to remove null_checkvp() altogether, or leave
it as a trivial stub, but not now.
Reported and tested by: pho
Diffstat (limited to 'sys/fs/nullfs/null_subr.c')
-rw-r--r-- | sys/fs/nullfs/null_subr.c | 29 |
1 files changed, 7 insertions, 22 deletions
diff --git a/sys/fs/nullfs/null_subr.c b/sys/fs/nullfs/null_subr.c index dd60ce8..5717a01 100644 --- a/sys/fs/nullfs/null_subr.c +++ b/sys/fs/nullfs/null_subr.c @@ -269,20 +269,14 @@ null_hashrem(xp) #ifdef DIAGNOSTIC -#ifdef KDB -#define null_checkvp_barrier 1 -#else -#define null_checkvp_barrier 0 -#endif - struct vnode * null_checkvp(vp, fil, lno) struct vnode *vp; char *fil; int lno; { - int interlock = 0; struct null_node *a = VTONULL(vp); + #ifdef notyet /* * Can't do this check because vop_reclaim runs @@ -290,9 +284,8 @@ null_checkvp(vp, fil, lno) */ if (vp->v_op != null_vnodeop_p) { printf ("null_checkvp: on non-null-node\n"); - while (null_checkvp_barrier) /*WAIT*/ ; panic("null_checkvp"); - }; + } #endif if (a->null_lowervp == NULLVP) { /* Should never happen */ @@ -301,32 +294,24 @@ null_checkvp(vp, fil, lno) for (p = (u_long *) a, i = 0; i < 8; i++) printf(" %lx", p[i]); printf("\n"); - /* wait for debugger */ - while (null_checkvp_barrier) /*WAIT*/ ; panic("null_checkvp"); } - if (mtx_owned(VI_MTX(vp)) != 0) { - VI_UNLOCK(vp); - interlock = 1; - } - if (vrefcnt(a->null_lowervp) < 1) { + VI_LOCK_FLAGS(a->null_lowervp, MTX_DUPOK); + if (a->null_lowervp->v_usecount < 1) { int i; u_long *p; printf("vp = %p, unref'ed lowervp\n", (void *)vp); for (p = (u_long *) a, i = 0; i < 8; i++) printf(" %lx", p[i]); printf("\n"); - /* wait for debugger */ - while (null_checkvp_barrier) /*WAIT*/ ; panic ("null with unref'ed lowervp"); - }; - if (interlock != 0) - VI_LOCK(vp); + } + VI_UNLOCK(a->null_lowervp); #ifdef notyet printf("null %x/%d -> %x/%d [%s, %d]\n", NULLTOV(a), vrefcnt(NULLTOV(a)), a->null_lowervp, vrefcnt(a->null_lowervp), fil, lno); #endif - return a->null_lowervp; + return (a->null_lowervp); } #endif |