summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/vfs_export.c39
-rw-r--r--sys/kern/vfs_subr.c39
-rw-r--r--sys/vm/vm_object.c5
3 files changed, 52 insertions, 31 deletions
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c
index dfa2017..0c1dc77 100644
--- a/sys/kern/vfs_export.c
+++ b/sys/kern/vfs_export.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
- * $Id: vfs_subr.c,v 1.86 1997/05/06 15:19:38 phk Exp $
+ * $Id: vfs_subr.c,v 1.87 1997/06/10 02:48:08 davidg Exp $
*/
/*
@@ -839,7 +839,8 @@ vget(vp, flags, p)
*/
if ((vp->v_type == VREG) &&
((vp->v_object == NULL) ||
- (vp->v_object->flags & OBJ_VFS_REF) == 0)) {
+ (vp->v_object->flags & OBJ_VFS_REF) == 0 ||
+ (vp->v_object->flags & OBJ_DEAD))) {
/*
* XXX vfs_object_create probably needs the interlock.
*/
@@ -1047,7 +1048,8 @@ vref(vp)
if ((vp->v_type == VREG) &&
((vp->v_object == NULL) ||
- ((vp->v_object->flags & OBJ_VFS_REF) == 0)) ) {
+ ((vp->v_object->flags & OBJ_VFS_REF) == 0) ||
+ (vp->v_object->flags & OBJ_DEAD))) {
/*
* We need to lock to VP during the time that
* the object is created. This is necessary to
@@ -1237,17 +1239,6 @@ loop:
continue;
}
- if (vp->v_object && (vp->v_object->flags & OBJ_VFS_REF)) {
- simple_unlock(&vp->v_interlock);
- simple_unlock(&mntvnode_slock);
- vm_object_reference(vp->v_object);
- pager_cache(vp->v_object, FALSE);
- vp->v_object->flags &= ~OBJ_VFS_REF;
- vm_object_deallocate(vp->v_object);
- simple_lock(&mntvnode_slock);
- simple_lock(&vp->v_interlock);
- }
-
/*
* With v_usecount == 0, all we need to do is clear out the
* vnode data structures and we are done.
@@ -1295,7 +1286,8 @@ loop:
static void
vclean(struct vnode *vp, int flags, struct proc *p)
{
- int active;
+ int active, irefed;
+ vm_object_t object;
/*
* Check to see if the vnode is in use. If so we have to reference it
@@ -1319,11 +1311,28 @@ vclean(struct vnode *vp, int flags, struct proc *p)
* occur while the underlying object is being cleaned out.
*/
VOP_LOCK(vp, LK_DRAIN | LK_INTERLOCK, p);
+
+ object = vp->v_object;
+ irefed = 0;
+ if (object && ((object->flags & OBJ_DEAD) == 0)) {
+ if (object->ref_count == 0) {
+ vm_object_reference(object);
+ irefed = 1;
+ }
+ ++object->ref_count;
+ pager_cache(object, FALSE);
+ }
+
/*
* Clean out any buffers associated with the vnode.
*/
if (flags & DOCLOSE)
vinvalbuf(vp, V_SAVE, NOCRED, p, 0, 0);
+
+ if (irefed) {
+ vm_object_deallocate(object);
+ }
+
/*
* If purging an active vnode, it must be closed and
* deactivated before being reclaimed. Note that the
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index dfa2017..0c1dc77 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
- * $Id: vfs_subr.c,v 1.86 1997/05/06 15:19:38 phk Exp $
+ * $Id: vfs_subr.c,v 1.87 1997/06/10 02:48:08 davidg Exp $
*/
/*
@@ -839,7 +839,8 @@ vget(vp, flags, p)
*/
if ((vp->v_type == VREG) &&
((vp->v_object == NULL) ||
- (vp->v_object->flags & OBJ_VFS_REF) == 0)) {
+ (vp->v_object->flags & OBJ_VFS_REF) == 0 ||
+ (vp->v_object->flags & OBJ_DEAD))) {
/*
* XXX vfs_object_create probably needs the interlock.
*/
@@ -1047,7 +1048,8 @@ vref(vp)
if ((vp->v_type == VREG) &&
((vp->v_object == NULL) ||
- ((vp->v_object->flags & OBJ_VFS_REF) == 0)) ) {
+ ((vp->v_object->flags & OBJ_VFS_REF) == 0) ||
+ (vp->v_object->flags & OBJ_DEAD))) {
/*
* We need to lock to VP during the time that
* the object is created. This is necessary to
@@ -1237,17 +1239,6 @@ loop:
continue;
}
- if (vp->v_object && (vp->v_object->flags & OBJ_VFS_REF)) {
- simple_unlock(&vp->v_interlock);
- simple_unlock(&mntvnode_slock);
- vm_object_reference(vp->v_object);
- pager_cache(vp->v_object, FALSE);
- vp->v_object->flags &= ~OBJ_VFS_REF;
- vm_object_deallocate(vp->v_object);
- simple_lock(&mntvnode_slock);
- simple_lock(&vp->v_interlock);
- }
-
/*
* With v_usecount == 0, all we need to do is clear out the
* vnode data structures and we are done.
@@ -1295,7 +1286,8 @@ loop:
static void
vclean(struct vnode *vp, int flags, struct proc *p)
{
- int active;
+ int active, irefed;
+ vm_object_t object;
/*
* Check to see if the vnode is in use. If so we have to reference it
@@ -1319,11 +1311,28 @@ vclean(struct vnode *vp, int flags, struct proc *p)
* occur while the underlying object is being cleaned out.
*/
VOP_LOCK(vp, LK_DRAIN | LK_INTERLOCK, p);
+
+ object = vp->v_object;
+ irefed = 0;
+ if (object && ((object->flags & OBJ_DEAD) == 0)) {
+ if (object->ref_count == 0) {
+ vm_object_reference(object);
+ irefed = 1;
+ }
+ ++object->ref_count;
+ pager_cache(object, FALSE);
+ }
+
/*
* Clean out any buffers associated with the vnode.
*/
if (flags & DOCLOSE)
vinvalbuf(vp, V_SAVE, NOCRED, p, 0, 0);
+
+ if (irefed) {
+ vm_object_deallocate(object);
+ }
+
/*
* If purging an active vnode, it must be closed and
* deactivated before being reclaimed. Note that the
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index abc2ce8..63f3552 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_object.c,v 1.91 1997/04/26 11:46:25 peter Exp $
+ * $Id: vm_object.c,v 1.92 1997/05/29 02:57:22 peter Exp $
*/
/*
@@ -372,6 +372,9 @@ vm_object_terminate(object)
register vm_page_t p;
int s;
+ if (object->flags & OBJ_VFS_REF)
+ panic("vm_object_deallocate: freeing VFS_REF'ed object");
+
/*
* wait for the pageout daemon to be done with the object
*/
OpenPOWER on IntegriCloud