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:
parent
6ece4a516d
commit
06cb725951
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=9456
@ -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) &&
|
||||
|
@ -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) &&
|
||||
|
@ -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) &&
|
||||
|
@ -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) &&
|
||||
|
@ -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) &&
|
||||
|
@ -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);
|
||||
/*
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user