summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-06-22 03:00:24 +0000
committerdyson <dyson@FreeBSD.org>1997-06-22 03:00:24 +0000
commit8786565a8667416801e00e004b227ee27c2656c9 (patch)
treeb024e0ecb8b4cb1cda6670f0f4deba38f23f97ba /sys
parent9aa9d790d1364010763c386c6c004018a9fc1f68 (diff)
downloadFreeBSD-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.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