summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-11-02 21:30:10 +0000
committeralc <alc@FreeBSD.org>2003-11-02 21:30:10 +0000
commit28e8cd183d9fd704019eb7317587d2a78d408bcb (patch)
treec444bccc0d758d1bb535604fed810ebf0d768d08 /sys
parent1bf95a39a6f845be3664583fb266063bcd3a003f (diff)
downloadFreeBSD-src-28e8cd183d9fd704019eb7317587d2a78d408bcb.zip
FreeBSD-src-28e8cd183d9fd704019eb7317587d2a78d408bcb.tar.gz
- Introduce and use vm_object_reference_locked(). Unlike
vm_object_reference(), this function must not be used to reanimate dead vm objects. This restriction simplifies locking. Reviewed by: tegge
Diffstat (limited to 'sys')
-rw-r--r--sys/vm/vm_map.c2
-rw-r--r--sys/vm/vm_object.c26
-rw-r--r--sys/vm/vm_object.h1
3 files changed, 26 insertions, 3 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index b09f4ee..956d048 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -2369,8 +2369,8 @@ vm_map_copy_entry(
}
}
- vm_object_reference(src_object);
VM_OBJECT_LOCK(src_object);
+ vm_object_reference_locked(src_object);
vm_object_clear_flag(src_object, OBJ_ONEMAPPING);
VM_OBJECT_UNLOCK(src_object);
dst_entry->object.vm_object = src_object;
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 2a03568..be68111 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -377,6 +377,28 @@ vm_object_reference(vm_object_t object)
}
/*
+ * vm_object_reference_locked:
+ *
+ * Gets another reference to the given object.
+ *
+ * The object must be locked.
+ */
+void
+vm_object_reference_locked(vm_object_t object)
+{
+ struct vnode *vp;
+
+ VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
+ KASSERT((object->flags & OBJ_DEAD) == 0,
+ ("vm_object_reference_locked: dead object referenced"));
+ object->ref_count++;
+ if (object->type == OBJT_VNODE) {
+ vp = object->handle;
+ vref(vp);
+ }
+}
+
+/*
* Handle deallocating an object of type OBJT_VNODE.
*/
void
@@ -1184,12 +1206,12 @@ vm_object_split(vm_map_entry_t entry)
source = orig_object->backing_object;
if (source != NULL) {
- vm_object_reference(source); /* Referenced by new_object */
VM_OBJECT_LOCK(source);
LIST_INSERT_HEAD(&source->shadow_head,
new_object, shadow_list);
source->shadow_count++;
source->generation++;
+ vm_object_reference_locked(source); /* for new_object */
vm_object_clear_flag(source, OBJ_ONEMAPPING);
VM_OBJECT_UNLOCK(source);
new_object->backing_object_offset =
@@ -1623,7 +1645,6 @@ vm_object_collapse(vm_object_t object)
new_backing_object = backing_object->backing_object;
if ((object->backing_object = new_backing_object) != NULL) {
- vm_object_reference(new_backing_object);
VM_OBJECT_LOCK(new_backing_object);
LIST_INSERT_HEAD(
&new_backing_object->shadow_head,
@@ -1632,6 +1653,7 @@ vm_object_collapse(vm_object_t object)
);
new_backing_object->shadow_count++;
new_backing_object->generation++;
+ vm_object_reference_locked(new_backing_object);
VM_OBJECT_UNLOCK(new_backing_object);
object->backing_object_offset +=
backing_object->backing_object_offset;
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
index 5371337..96d8666 100644
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -213,6 +213,7 @@ void vm_object_init (void);
void vm_object_page_clean (vm_object_t, vm_pindex_t, vm_pindex_t, boolean_t);
void vm_object_page_remove (vm_object_t, vm_pindex_t, vm_pindex_t, boolean_t);
void vm_object_reference (vm_object_t);
+void vm_object_reference_locked(vm_object_t);
void vm_object_shadow (vm_object_t *, vm_ooffset_t *, vm_size_t);
void vm_object_split(vm_map_entry_t);
void vm_object_madvise (vm_object_t, vm_pindex_t, int, int);
OpenPOWER on IntegriCloud