diff options
| author | Stephan Uphoff <ups@FreeBSD.org> | 2008-05-20 19:05:43 +0000 |
|---|---|---|
| committer | Stephan Uphoff <ups@FreeBSD.org> | 2008-05-20 19:05:43 +0000 |
| commit | 2ac78f0e1a784ff14218e3f5320f4c6269b4eb78 (patch) | |
| tree | 122fb04f7bf2895af8ccd1d933a2cf8c59347db2 | |
| parent | c54a18d26b6afde430af32090857d70da0983532 (diff) | |
Notes
| -rw-r--r-- | sys/ufs/ufs/ufs_lookup.c | 10 | ||||
| -rw-r--r-- | sys/vm/vm_object.c | 36 | ||||
| -rw-r--r-- | sys/vm/vm_object.h | 1 | ||||
| -rw-r--r-- | sys/vm/vnode_pager.c | 22 |
4 files changed, 51 insertions, 18 deletions
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 0a2f532d95c9..467f08454056 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -168,6 +168,16 @@ ufs_lookup(ap) 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. * diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 041b2890f3d6..4aed5e7114f9 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -594,6 +594,30 @@ doterm: } /* + * 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_object_terminate(vm_object_t object) 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); } /* diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index 4f9cad43cebd..e6f605ab095d 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -202,6 +202,7 @@ void _vm_object_allocate (objtype_t, vm_pindex_t, vm_object_t); 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); diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 4d6cea26bd3a..40e75d9827ed 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -198,15 +198,14 @@ vnode_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, 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 @@ vnode_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, 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 @@ vnode_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, 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); } |
