Index: ufs/ufs/ufs_lookup.c =================================================================== --- ufs/ufs/ufs_lookup.c (revision 179158) +++ ufs/ufs/ufs_lookup.c (revision 179159) @@ -168,7 +168,17 @@ vdp = ap->a_dvp; dp = VTOI(vdp); + /* + * Create a vm object if vmiodirenable is enabled. + * Alternatively we could call vnode_create_vobject + * in VFS_VGET but we could end up creating objects + * that are never used. + */ + + vnode_create_vobject(vdp, DIP(dp, i_size), cnp->cn_thread); + + /* * We now have a segment name to search for, and a directory to search. * * Suppress search for slots unless creating Index: vm/vm_object.c =================================================================== --- vm/vm_object.c (revision 179158) +++ vm/vm_object.c (revision 179159) @@ -594,6 +594,30 @@ } /* + * vm_object_destroy removes the object from the global object list + * and frees the space for the object. + */ +void +vm_object_destroy(vm_object_t object) +{ + + /* + * Remove the object from the global object list. + */ + mtx_lock(&vm_object_list_mtx); + TAILQ_REMOVE(&vm_object_list, object, object_list); + mtx_unlock(&vm_object_list_mtx); + + /* + * Free the space for the object. + */ + uma_zfree(obj_zone, object); + +} + + + +/* * vm_object_terminate actually destroys the specified object, freeing * up all previously used resources. * @@ -674,17 +698,7 @@ vm_pager_deallocate(object); VM_OBJECT_UNLOCK(object); - /* - * Remove the object from the global object list. - */ - mtx_lock(&vm_object_list_mtx); - TAILQ_REMOVE(&vm_object_list, object, object_list); - mtx_unlock(&vm_object_list_mtx); - - /* - * Free the space for the object. - */ - uma_zfree(obj_zone, object); + vm_object_destroy(object); } /* Index: vm/vm_object.h =================================================================== --- vm/vm_object.h (revision 179158) +++ vm/vm_object.h (revision 179159) @@ -202,6 +202,7 @@ boolean_t vm_object_coalesce(vm_object_t, vm_ooffset_t, vm_size_t, vm_size_t); void vm_object_collapse (vm_object_t); void vm_object_deallocate (vm_object_t); +void vm_object_destroy (vm_object_t); void vm_object_terminate (vm_object_t); void vm_object_set_writeable_dirty (vm_object_t); void vm_object_init (void); Index: vm/vnode_pager.c =================================================================== --- vm/vnode_pager.c (revision 179158) +++ vm/vnode_pager.c (revision 179159) @@ -198,15 +198,14 @@ vp = (struct vnode *) handle; - ASSERT_VOP_ELOCKED(vp, "vnode_pager_alloc"); - /* * If the object is being terminated, wait for it to * go away. */ +retry: while ((object = vp->v_object) != NULL) { VM_OBJECT_LOCK(object); - if ((object->flags & OBJ_DEAD) == 0) + if ((object->flags & OBJ_DEAD) == 0) break; vm_object_set_flag(object, OBJ_DISCONNECTWNT); msleep(object, VM_OBJECT_MTX(object), PDROP | PVM, "vadead", 0); @@ -217,7 +216,7 @@ if (object == NULL) { /* - * And an object of the appropriate size + * Add an object of the appropriate size */ object = vm_object_allocate(OBJT_VNODE, OFF_TO_IDX(round_page(size))); @@ -226,11 +225,20 @@ object->handle = handle; if (VFS_NEEDSGIANT(vp->v_mount)) vm_object_set_flag(object, OBJ_NEEDGIANT); + VM_OBJECT_LOCK(object); + if ( vp->v_object != NULL) { + /* + * Object has been created while we were sleeping + */ + VM_OBJECT_UNLOCK(object); + vm_object_destroy(object); + goto retry; + } vp->v_object = object; - } else { + } else object->ref_count++; - VM_OBJECT_UNLOCK(object); - } + + VM_OBJECT_UNLOCK(object); vref(vp); return (object); }