When a vnode-backed vm object is referenced, it increments the vnode

reference count, and decrements it on dereference. If referenced object
is deallocated, object type is reset to OBJT_DEAD. Consequently, all
vnode references that are owned by object references are never released.
vunref() the vnode in vm object deallocation code for OBJT_VNODE
appropriate number of times to prevent leak.

Add an assertion to the vm_pageout() to make sure that we never get
reference on the vnode but then do not execute code to release it.

In collaboration with:	pho
Reviewed by:	alc
MFC after:	3 weeks
This commit is contained in:
Konstantin Belousov 2010-01-17 21:26:14 +00:00
parent d2f334bfc9
commit b9f180d1de
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=202529
2 changed files with 8 additions and 1 deletions

View File

@ -951,6 +951,8 @@ rescan0:
vnodes_skipped++;
goto unlock_and_continue;
}
KASSERT(mp != NULL,
("vp %p with NULL v_mount", vp));
vm_page_unlock_queues();
vm_object_reference_locked(object);
VM_OBJECT_UNLOCK(object);

View File

@ -250,13 +250,16 @@ static void
vnode_pager_dealloc(object)
vm_object_t object;
{
struct vnode *vp = object->handle;
struct vnode *vp;
int refs;
vp = object->handle;
if (vp == NULL)
panic("vnode_pager_dealloc: pager already dealloced");
VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
vm_object_pip_wait(object, "vnpdea");
refs = object->ref_count;
object->handle = NULL;
object->type = OBJT_DEAD;
@ -267,6 +270,8 @@ vnode_pager_dealloc(object)
ASSERT_VOP_ELOCKED(vp, "vnode_pager_dealloc");
vp->v_object = NULL;
vp->v_vflag &= ~VV_TEXT;
while (refs-- > 0)
vunref(vp);
}
static boolean_t