Clarify the vnode_destroy_vobject() logic handling for already terminated

objects.

Assert that there is no new waiters for the already terminated objects.
Old waiters should have been notified by the termination calling
vnode_pager_dealloc() (old/new are with regard of the lock acquisition
interval).

Only clear the vp->v_object for the case of already terminated object,
since other branches call vnode_pager_dealloc(), which should clear
the pointer.  Assert this.

Tested by:	pho
Reviewed by:	alc
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
Approved by:	re (gjb)
This commit is contained in:
Konstantin Belousov 2016-07-05 11:21:02 +00:00
parent 8ac248ea27
commit 90880a1b29
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=302343

View File

@ -169,10 +169,21 @@ vnode_destroy_vobject(struct vnode *vp)
/*
* don't double-terminate the object
*/
if ((obj->flags & OBJ_DEAD) == 0)
if ((obj->flags & OBJ_DEAD) == 0) {
vm_object_terminate(obj);
else
} else {
/*
* Waiters were already handled during object
* termination. The exclusive vnode lock hopefully
* prevented new waiters from referencing the dying
* object.
*/
KASSERT((obj->flags & OBJ_DISCONNECTWNT) == 0,
("OBJ_DISCONNECTWNT set obj %p flags %x",
obj, obj->flags));
vp->v_object = NULL;
VM_OBJECT_WUNLOCK(obj);
}
} else {
/*
* Woe to the process that tries to page now :-).
@ -180,7 +191,7 @@ vnode_destroy_vobject(struct vnode *vp)
vm_pager_deallocate(obj);
VM_OBJECT_WUNLOCK(obj);
}
vp->v_object = NULL;
KASSERT(vp->v_object == NULL, ("vp %p obj %p", vp, vp->v_object));
}