Fixed an object allocation race condition that was causing a "object

deallocated too many times" panic when using NFS.

Reviewed by:	John Dyson
This commit is contained in:
David Greenman 1995-07-06 11:48:48 +00:00
parent bea0b497a1
commit 39d38f93e2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=9411
2 changed files with 47 additions and 24 deletions

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vnode.h 8.7 (Berkeley) 2/4/94
* $Id: vnode.h,v 1.20 1995/04/20 03:18:19 julian Exp $
* $Id: vnode.h,v 1.21 1995/06/28 12:01:07 davidg Exp $
*/
#ifndef _SYS_VNODE_H_
@ -107,16 +107,18 @@ struct vnode {
/*
* Vnode flags.
*/
#define VROOT 0x0001 /* root of its file system */
#define VTEXT 0x0002 /* vnode is a pure text prototype */
#define VSYSTEM 0x0004 /* vnode being used by kernel */
#define VXLOCK 0x0100 /* vnode is locked to change underlying type */
#define VXWANT 0x0200 /* process is waiting for vnode */
#define VBWAIT 0x0400 /* waiting for output to complete */
#define VALIASED 0x0800 /* vnode has an alias */
#define VDIROP 0x1000 /* LFS: vnode is involved in a directory op */
#define VROOT 0x0001 /* root of its file system */
#define VTEXT 0x0002 /* vnode is a pure text prototype */
#define VSYSTEM 0x0004 /* vnode being used by kernel */
#define VOLOCK 0x0008 /* vnode is locked waiting for an object */
#define VOWANT 0x0010 /* a process is waiting for VOLOCK */
#define VXLOCK 0x0100 /* vnode is locked to change underlying type */
#define VXWANT 0x0200 /* process is waiting for vnode */
#define VBWAIT 0x0400 /* waiting for output to complete */
#define VALIASED 0x0800 /* vnode has an alias */
#define VDIROP 0x1000 /* LFS: vnode is involved in a directory op */
#define VVMIO 0x2000 /* VMIO flag */
#define VNINACT 0x4000 /* LFS: skip ufs_inactive() in lfs_vunref */
#define VNINACT 0x4000 /* LFS: skip ufs_inactive() in lfs_vunref */
#define VAGE 0x8000 /* Insert vnode at head of free list */
/*

View File

@ -37,7 +37,7 @@
* SUCH DAMAGE.
*
* from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
* $Id: vnode_pager.c,v 1.40 1995/05/30 08:16:23 rgrimes Exp $
* $Id: vnode_pager.c,v 1.41 1995/06/28 12:01:13 davidg Exp $
*/
/*
@ -136,13 +136,23 @@ vnode_pager_alloc(handle, size, prot, offset)
if (handle == NULL)
return (NULL);
/*
* Vnodes keep a pointer to any associated pager so no need to lookup
* with vm_pager_lookup.
*/
vp = (struct vnode *) handle;
while ((object = vp->v_object) &&
(object->flags & OBJ_DEAD))
/*
* Prevent race condition when allocating the object. This
* can happen with NFS vnodes since the nfsnode isn't locked.
*/
while (vp->v_flag & VOLOCK) {
vp->v_flag |= VOWANT;
tsleep(vp, PVM, "vnpobj", 0);
}
vp->v_flag |= VOLOCK;
/*
* If the object is being terminated, wait for it to
* go away.
*/
while (((object = vp->v_object) != NULL) && (object->flags & OBJ_DEAD))
tsleep(object, PVM, "vadead", 0);
pager = NULL;
@ -154,13 +164,8 @@ vnode_pager_alloc(handle, size, prot, offset)
* Allocate pager structures
*/
pager = (vm_pager_t) malloc(sizeof *pager, M_VMPAGER, M_WAITOK);
if (pager == NULL)
return (NULL);
vnp = (vn_pager_t) malloc(sizeof *vnp, M_VMPGDATA, M_WAITOK);
if (vnp == NULL) {
free((caddr_t) pager, M_VMPAGER);
return (NULL);
}
/*
* And an object of the appropriate size
*/
@ -170,6 +175,15 @@ vnode_pager_alloc(handle, size, prot, offset)
vm_object_enter(object, pager);
object->pager = pager;
} else {
/*
* The VOP_GETATTR failed...
* Unlock, wakeup any waiters, free pagers, and exit.
*/
vp->v_flag &= ~VOLOCK;
if (vp->v_flag & VOWANT) {
vp->v_flag &= ~VOWANT;
wakeup(vp);
}
free((caddr_t) vnp, M_VMPGDATA);
free((caddr_t) pager, M_VMPAGER);
return (NULL);
@ -197,8 +211,15 @@ vnode_pager_alloc(handle, size, prot, offset)
*/
(void) vm_object_lookup(pager);
}
if( vp->v_type == VREG)
if (vp->v_type == VREG)
vp->v_flag |= VVMIO;
vp->v_flag &= ~VOLOCK;
if (vp->v_flag & VOWANT) {
vp->v_flag &= ~VOWANT;
wakeup(vp);
}
return (pager);
}