diff options
author | Pedro Martelletto <pedro@cvs.openbsd.org> | 2005-01-10 11:58:35 +0000 |
---|---|---|
committer | Pedro Martelletto <pedro@cvs.openbsd.org> | 2005-01-10 11:58:35 +0000 |
commit | 904907a5fdbb96650fa67391bc667417cfdfd2f4 (patch) | |
tree | b63b916f208613932b4760e899923ea91e2002bd /sys/kern | |
parent | ba6cd06600e1a01263181dfa72b329ba670594d5 (diff) |
change vget() to only put a vnode back on the free lists if it actually
was there. should fix a (rare) corner case introduced by my last commit.
ok tedu@, testing by joris, moritz@, danh@, otto@ and krw@. many thanks.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_subr.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 4c1eda42b50..1068ce3d8e7 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_subr.c,v 1.108 2004/12/31 15:28:40 pedro Exp $ */ +/* $OpenBSD: vfs_subr.c,v 1.109 2005/01/10 11:58:34 pedro Exp $ */ /* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */ /* @@ -661,8 +661,7 @@ vget(vp, flags, p) int flags; struct proc *p; { - int error; - int s; + int error, s, onfreelist; /* * If the vnode is in the process of being cleaned out for @@ -686,8 +685,8 @@ vget(vp, flags, p) return (ENOENT); } - if (vp->v_usecount == 0 && - (vp->v_bioflag & VBIOONFREELIST)) { + onfreelist = vp->v_bioflag & VBIOONFREELIST; + if (vp->v_usecount == 0 && onfreelist) { s = splbio(); simple_lock(&vnode_free_list_slock); if (vp->v_holdcnt > 0) @@ -698,18 +697,21 @@ vget(vp, flags, p) vp->v_bioflag &= ~VBIOONFREELIST; splx(s); } + vp->v_usecount++; if (flags & LK_TYPE_MASK) { if ((error = vn_lock(vp, flags, p)) != 0) { vp->v_usecount--; - if (vp->v_usecount == 0) + if (vp->v_usecount == 0 && onfreelist) vputonfreelist(vp); simple_unlock(&vp->v_interlock); } return (error); } + simple_unlock(&vp->v_interlock); + return (0); } |