summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_page.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_page.c')
-rw-r--r--sys/vm/vm_page.c29
1 files changed, 10 insertions, 19 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index d9a8467..2e3211f 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -575,6 +575,11 @@ vm_page_insert(vm_page_t m, vm_object_t object, vm_pindex_t pindex)
* show that the object has one more resident page.
*/
object->resident_page_count++;
+ /*
+ * Hold the vnode until the last page is released.
+ */
+ if (object->resident_page_count == 1 && object->type == OBJT_VNODE)
+ vhold((struct vnode *)object->handle);
/*
* Since we are inserting a new and possibly dirty page,
@@ -630,6 +635,11 @@ vm_page_remove(vm_page_t m)
*/
object->resident_page_count--;
object->generation++;
+ /*
+ * The vnode may now be recycled.
+ */
+ if (object->resident_page_count == 0 && object->type == OBJT_VNODE)
+ vdrop((struct vnode *)object->handle);
m->object = NULL;
}
@@ -995,7 +1005,6 @@ void
vm_page_free_toq(vm_page_t m)
{
struct vpgqueues *pq;
- vm_object_t object = m->object;
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
cnt.v_tfree++;
@@ -1040,24 +1049,6 @@ vm_page_free_toq(vm_page_t m)
}
/*
- * If we've exhausted the object's resident pages we want to free
- * it up.
- */
- if (object &&
- (object->type == OBJT_VNODE) &&
- ((object->flags & OBJ_DEAD) == 0)
- ) {
- struct vnode *vp = (struct vnode *)object->handle;
-
- if (vp) {
- VI_LOCK(vp);
- if (VSHOULDFREE(vp))
- vfree(vp);
- VI_UNLOCK(vp);
- }
- }
-
- /*
* Clear the UNMANAGED flag when freeing an unmanaged page.
*/
if (m->flags & PG_UNMANAGED) {
OpenPOWER on IntegriCloud