diff options
author | dyson <dyson@FreeBSD.org> | 1997-06-22 03:00:24 +0000 |
---|---|---|
committer | dyson <dyson@FreeBSD.org> | 1997-06-22 03:00:24 +0000 |
commit | 8786565a8667416801e00e004b227ee27c2656c9 (patch) | |
tree | b024e0ecb8b4cb1cda6670f0f4deba38f23f97ba /sys | |
parent | 9aa9d790d1364010763c386c6c004018a9fc1f68 (diff) | |
download | FreeBSD-src-8786565a8667416801e00e004b227ee27c2656c9.zip FreeBSD-src-8786565a8667416801e00e004b227ee27c2656c9.tar.gz |
Remove a window during running down a file vnode. Also, the OBJ_DEAD
flag wasn't being respected during vref(), et. al. Note that this
isn't the eventual fix for the locking problem. Fine grained SMP
in the VM and VFS code will require (lots) more work.
Diffstat (limited to 'sys')
-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 */ |