Moved call to VOP_GETATTR() out of vnode_pager_alloc() and into the places

that call vnode_pager_alloc() so that a failure return can be dealt with.
This fixes a panic seen on NFS clients when a file being opened is deleted
on the server before the open completes.
This commit is contained in:
David Greenman 1995-07-09 06:58:03 +00:00
parent 6ece4a516d
commit 06cb725951
7 changed files with 77 additions and 54 deletions

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94
* $Id: vfs_vnops.c,v 1.12 1995/06/28 12:00:58 davidg Exp $
* $Id: vfs_vnops.c,v 1.13 1995/06/28 12:32:47 davidg Exp $
*/
#include <sys/param.h>
@ -161,8 +161,11 @@ vn_open(ndp, fmode, cmode)
vm_pager_t pager;
retry:
if ((vp->v_flag & VVMIO) == 0) {
if (vnode_pager_alloc(vp, 0, 0, 0) == NULL)
panic("vn_open: failed to alloc pager");
error = VOP_GETATTR(vp, vap, cred, p);
if (error)
goto bad;
if (vnode_pager_alloc(vp, vap->va_size, 0, 0) == NULL)
panic("vn_open: failed to allocate object");
vp->v_flag |= VVMIO;
} else {
if ((object = vp->v_object) &&

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
* $Id: nfs_subs.c,v 1.17 1995/06/27 11:06:47 dfr Exp $
* $Id: nfs_subs.c,v 1.18 1995/06/28 12:01:05 davidg Exp $
*/
/*
@ -1905,8 +1905,15 @@ nfsrv_vmio(struct vnode *vp) {
retry:
if ((vp->v_flag & VVMIO) == 0) {
if (vnode_pager_alloc(vp, 0, 0, 0) == NULL)
panic("nfsrv_vmio: failed to alloc pager");
struct vattr vat;
struct proc *p = curproc;
if (VOP_GETATTR(vp, &vat, p->p_ucred, p) != 0)
panic("nfsrv_vmio: VOP_GETATTR failed");
if (vnode_pager_alloc(vp, vat.va_size, 0, 0) == NULL)
panic("nfsrv_vmio: vnode_pager_alloc failed");
vp->v_flag |= VVMIO;
} else {
if ((object = vp->v_object) &&

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
* $Id: nfs_subs.c,v 1.17 1995/06/27 11:06:47 dfr Exp $
* $Id: nfs_subs.c,v 1.18 1995/06/28 12:01:05 davidg Exp $
*/
/*
@ -1905,8 +1905,15 @@ nfsrv_vmio(struct vnode *vp) {
retry:
if ((vp->v_flag & VVMIO) == 0) {
if (vnode_pager_alloc(vp, 0, 0, 0) == NULL)
panic("nfsrv_vmio: failed to alloc pager");
struct vattr vat;
struct proc *p = curproc;
if (VOP_GETATTR(vp, &vat, p->p_ucred, p) != 0)
panic("nfsrv_vmio: VOP_GETATTR failed");
if (vnode_pager_alloc(vp, vat.va_size, 0, 0) == NULL)
panic("nfsrv_vmio: vnode_pager_alloc failed");
vp->v_flag |= VVMIO;
} else {
if ((object = vp->v_object) &&

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
* $Id: nfs_subs.c,v 1.17 1995/06/27 11:06:47 dfr Exp $
* $Id: nfs_subs.c,v 1.18 1995/06/28 12:01:05 davidg Exp $
*/
/*
@ -1905,8 +1905,15 @@ nfsrv_vmio(struct vnode *vp) {
retry:
if ((vp->v_flag & VVMIO) == 0) {
if (vnode_pager_alloc(vp, 0, 0, 0) == NULL)
panic("nfsrv_vmio: failed to alloc pager");
struct vattr vat;
struct proc *p = curproc;
if (VOP_GETATTR(vp, &vat, p->p_ucred, p) != 0)
panic("nfsrv_vmio: VOP_GETATTR failed");
if (vnode_pager_alloc(vp, vat.va_size, 0, 0) == NULL)
panic("nfsrv_vmio: vnode_pager_alloc failed");
vp->v_flag |= VVMIO;
} else {
if ((object = vp->v_object) &&

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
* $Id: nfs_subs.c,v 1.17 1995/06/27 11:06:47 dfr Exp $
* $Id: nfs_subs.c,v 1.18 1995/06/28 12:01:05 davidg Exp $
*/
/*
@ -1905,8 +1905,15 @@ nfsrv_vmio(struct vnode *vp) {
retry:
if ((vp->v_flag & VVMIO) == 0) {
if (vnode_pager_alloc(vp, 0, 0, 0) == NULL)
panic("nfsrv_vmio: failed to alloc pager");
struct vattr vat;
struct proc *p = curproc;
if (VOP_GETATTR(vp, &vat, p->p_ucred, p) != 0)
panic("nfsrv_vmio: VOP_GETATTR failed");
if (vnode_pager_alloc(vp, vat.va_size, 0, 0) == NULL)
panic("nfsrv_vmio: vnode_pager_alloc failed");
vp->v_flag |= VVMIO;
} else {
if ((object = vp->v_object) &&

View File

@ -38,7 +38,7 @@
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
*
* @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
* $Id: vm_mmap.c,v 1.23 1995/05/18 02:59:24 davidg Exp $
* $Id: vm_mmap.c,v 1.24 1995/05/30 08:16:09 rgrimes Exp $
*/
/*
@ -609,21 +609,13 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
struct vnode *vp = NULL;
int type;
int rv = KERN_SUCCESS;
vm_size_t objsize;
struct proc *p = curproc;
if (size == 0)
return (0);
size = round_page(size);
if ((flags & MAP_FIXED) == 0) {
fitit = TRUE;
*addr = round_page(*addr);
} else {
if (*addr != trunc_page(*addr))
return (EINVAL);
fitit = FALSE;
(void) vm_map_remove(map, *addr, *addr + size);
}
objsize = size = round_page(size);
/*
* We currently can only deal with page aligned file offsets.
@ -636,6 +628,16 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
if (foff & PAGE_MASK)
return (EINVAL);
if ((flags & MAP_FIXED) == 0) {
fitit = TRUE;
*addr = round_page(*addr);
} else {
if (*addr != trunc_page(*addr))
return (EINVAL);
fitit = FALSE;
(void) vm_map_remove(map, *addr, *addr + size);
}
/*
* Lookup/allocate pager. All except an unnamed anonymous lookup gain
* a reference to ensure continued existance of the object. (XXX the
@ -653,10 +655,18 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
if (vp->v_type == VCHR) {
type = PG_DEVICE;
handle = (caddr_t) vp->v_rdev;
} else
} else {
struct vattr vat;
int error;
error = VOP_GETATTR(vp, &vat, p->p_ucred, p);
if (error)
return (error);
objsize = vat.va_size;
type = PG_VNODE;
}
}
pager = vm_pager_allocate(type, handle, size, prot, foff);
pager = vm_pager_allocate(type, handle, objsize, prot, foff);
if (pager == NULL)
return (type == PG_DEVICE ? EINVAL : ENOMEM);
/*

View File

@ -37,7 +37,7 @@
* SUCH DAMAGE.
*
* from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
* $Id: vnode_pager.c,v 1.41 1995/06/28 12:01:13 davidg Exp $
* $Id: vnode_pager.c,v 1.42 1995/07/06 11:48:48 davidg Exp $
*/
/*
@ -124,11 +124,8 @@ vnode_pager_alloc(handle, size, prot, offset)
{
register vm_pager_t pager;
register vn_pager_t vnp;
vm_object_t object, tobject;
struct vattr vattr;
vm_object_t object;
struct vnode *vp;
struct proc *p = curproc; /* XXX */
int rtval;
/*
* Pageout to vnode, no can do yet.
@ -169,25 +166,10 @@ vnode_pager_alloc(handle, size, prot, offset)
/*
* And an object of the appropriate size
*/
if ((rtval = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) == 0) {
object = vm_object_allocate(round_page(vattr.va_size));
object->flags = OBJ_CANPERSIST;
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);
}
object = vm_object_allocate(round_page(size));
object->flags = OBJ_CANPERSIST;
vm_object_enter(object, pager);
object->pager = pager;
/*
* Hold a reference to the vnode and initialize pager data.
@ -195,7 +177,7 @@ vnode_pager_alloc(handle, size, prot, offset)
VREF(vp);
vnp->vnp_flags = 0;
vnp->vnp_vp = vp;
vnp->vnp_size = vattr.va_size;
vnp->vnp_size = size;
TAILQ_INSERT_TAIL(&vnode_pager_list, pager, pg_list);
pager->pg_handle = handle;