aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Uphoff <ups@FreeBSD.org>2008-05-20 19:05:43 +0000
committerStephan Uphoff <ups@FreeBSD.org>2008-05-20 19:05:43 +0000
commit2ac78f0e1a784ff14218e3f5320f4c6269b4eb78 (patch)
tree122fb04f7bf2895af8ccd1d933a2cf8c59347db2
parentc54a18d26b6afde430af32090857d70da0983532 (diff)
Notes
-rw-r--r--sys/ufs/ufs/ufs_lookup.c10
-rw-r--r--sys/vm/vm_object.c36
-rw-r--r--sys/vm/vm_object.h1
-rw-r--r--sys/vm/vnode_pager.c22
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);
}