summaryrefslogtreecommitdiff
path: root/sys/uvm/uvm_vnode.c
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-04-05 18:11:04 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-04-05 18:11:04 +0000
commit1a03b3dfdd4ed1dc9828da2b82f842476ba80995 (patch)
tree27b3952a7aebc426b5a3e6bfcac566204eee9d40 /sys/uvm/uvm_vnode.c
parent700acdc13eff8dedc253ebd5a7035e5219a137d1 (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.c4
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);
}
}