diff options
author | dg <dg@FreeBSD.org> | 1995-07-09 06:58:03 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1995-07-09 06:58:03 +0000 |
commit | 24d64ff84ab71285665b581743c53984211e76b5 (patch) | |
tree | 500681c97211690541fd1a154b0223e263ed5ab0 /sys/vm | |
parent | 0e9d5904c5f4ac85436f5db08213874f2488f5c1 (diff) | |
download | FreeBSD-src-24d64ff84ab71285665b581743c53984211e76b5.zip FreeBSD-src-24d64ff84ab71285665b581743c53984211e76b5.tar.gz |
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.
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vm_mmap.c | 38 | ||||
-rw-r--r-- | sys/vm/vnode_pager.c | 32 |
2 files changed, 31 insertions, 39 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 1f9c041..106b62b 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -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); /* diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index b29b4ff..c24d3e5 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -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; |