diff options
-rw-r--r-- | sys/kern/vfs_export.c | 39 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 39 | ||||
-rw-r--r-- | sys/vm/vm_object.c | 5 |
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 */ |