diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-04-05 18:11:04 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-04-05 18:11:04 +0000 |
commit | 1a03b3dfdd4ed1dc9828da2b82f842476ba80995 (patch) | |
tree | 27b3952a7aebc426b5a3e6bfcac566204eee9d40 /sys/uvm/uvm_vnode.c | |
parent | 700acdc13eff8dedc253ebd5a7035e5219a137d1 (diff) |
In the unlikely even that we do the final unref on a uvm_vnode object
while there's io pending (async io makes that possible, but not often
hit), then we'll be waiting for the pgo_releasepg hook to free the
object when all of our pages disappear.
However, uvn_releasepg, while it does everything else that unreferencing
the object would do, it neglects to do the final vrele() on the vnode.
So in this rare situation we'd end up with the vnode waiting around
until it was forcibly recycled. Fix this by adding in the missing vrele().
ok thib@
Diffstat (limited to 'sys/uvm/uvm_vnode.c')
-rw-r--r-- | sys/uvm/uvm_vnode.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/sys/uvm/uvm_vnode.c b/sys/uvm/uvm_vnode.c index 4316c4eb908..138fb9dab22 100644 --- a/sys/uvm/uvm_vnode.c +++ b/sys/uvm/uvm_vnode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_vnode.c,v 1.53 2009/03/20 15:19:04 oga Exp $ */ +/* $OpenBSD: uvm_vnode.c,v 1.54 2009/04/05 18:11:03 oga Exp $ */ /* $NetBSD: uvm_vnode.c,v 1.36 2000/11/24 20:34:01 chs Exp $ */ /* @@ -650,6 +650,7 @@ boolean_t uvn_releasepg(struct vm_page *pg, struct vm_page **nextpgp /* OUT */) { struct uvm_vnode *uvn = (struct uvm_vnode *) pg->uobject; + struct vnode *vp = (struct vnode *)uvn; #ifdef DIAGNOSTIC if ((pg->pg_flags & PG_RELEASED) == 0) panic("uvn_releasepg: page not released!"); @@ -687,6 +688,7 @@ uvn_releasepg(struct vm_page *pg, struct vm_page **nextpgp /* OUT */) uvn->u_flags = 0; /* DEAD! */ simple_unlock(&uvn->u_obj.vmobjlock); + vrele(vp); return (FALSE); } } |