From 90880a1b29da0f504ffba54b19d53fdea9b06090 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 5 Jul 2016 11:21:02 +0000 Subject: [PATCH] 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) --- sys/vm/vnode_pager.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index cc439766c967..a80a9c24fd60 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -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)); }