From e5f299ff760fec7221780cc019707658969a57d4 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 28 Apr 2013 19:25:09 +0000 Subject: [PATCH] Make vm_object_page_clean() and vm_mmap_vnode() tolerate the vnode' v_object of non OBJT_VNODE type. For vm_object_page_clean(), simply do not assert that object type must be OBJT_VNODE, and add a comment explaining how the check for OBJ_MIGHTBEDIRTY prevents the rest of function from operating on such objects. For vm_mmap_vnode(), if the object type is not OBJT_VNODE, require it to be for swap pager (or default), handle the bypass filesystems, and correctly acquire the object reference in this case. Reviewed by: alc Tested by: pho, bf MFC after: 1 week --- sys/vm/vm_mmap.c | 11 +++++++++-- sys/vm/vm_object.c | 7 ++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index c17e9cee9ce6..ef63f850ed00 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -1284,7 +1284,7 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize, error = EINVAL; goto done; } - if (obj->handle != vp) { + if (obj->type == OBJT_VNODE && obj->handle != vp) { vput(vp); vp = (struct vnode *)obj->handle; /* @@ -1333,7 +1333,14 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize, objsize = round_page(va.va_size); if (va.va_nlink == 0) flags |= MAP_NOSYNC; - obj = vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff, cred); + if (obj->type == OBJT_VNODE) + obj = vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff, + cred); + else { + KASSERT(obj->type == OBJT_DEFAULT || obj->type == OBJT_SWAP, + ("wrong object type")); + vm_object_reference(obj); + } if (obj == NULL) { error = ENOMEM; goto done; diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 3d9ec616b18c..1f7cb7881a8b 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -820,7 +820,12 @@ vm_object_page_clean(vm_object_t object, vm_ooffset_t start, vm_ooffset_t end, boolean_t clearobjflags, eio, res; VM_OBJECT_ASSERT_WLOCKED(object); - KASSERT(object->type == OBJT_VNODE, ("Not a vnode object")); + + /* + * The OBJ_MIGHTBEDIRTY flag is only set for OBJT_VNODE + * objects. The check below prevents the function from + * operating on non-vnode objects. + */ if ((object->flags & OBJ_MIGHTBEDIRTY) == 0 || object->resident_page_count == 0) return (TRUE);