From 07a6c3ab4ed79dd790146ab334bbd17a33f1770d Mon Sep 17 00:00:00 2001 From: alc Date: Sat, 14 Oct 2006 22:09:03 +0000 Subject: [PATCH] Change vnode_pager_addr() such that on returning it distinguishes between an error returned by VOP_BMAP() and a hole in the file. Change the callers to vnode_pager_addr() such that they return VM_PAGER_ERROR when VOP_BMAP fails instead of a zero-filled page. Reviewed by: tegge MFC after: 3 weeks --- sys/vm/vnode_pager.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index b4a9bf6b9120..e6b88cd8737e 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -75,8 +75,8 @@ __FBSDID("$FreeBSD$"); #include #include -static daddr_t vnode_pager_addr(struct vnode *vp, vm_ooffset_t address, - int *run); +static int vnode_pager_addr(struct vnode *vp, vm_ooffset_t address, + daddr_t *rtaddress, int *run); static int vnode_pager_input_smlfs(vm_object_t object, vm_page_t m); static int vnode_pager_input_old(vm_object_t object, vm_page_t m); static void vnode_pager_dealloc(vm_object_t); @@ -437,15 +437,11 @@ vnode_pager_setsize(vp, nsize) * calculate the linear (byte) disk address of specified virtual * file address */ -static daddr_t -vnode_pager_addr(vp, address, run) - struct vnode *vp; - vm_ooffset_t address; - int *run; +static int +vnode_pager_addr(struct vnode *vp, vm_ooffset_t address, daddr_t *rtaddress, + int *run) { - daddr_t rtaddress; int bsize; - daddr_t block; int err; daddr_t vblock; daddr_t voffset; @@ -460,12 +456,10 @@ vnode_pager_addr(vp, address, run) vblock = address / bsize; voffset = address % bsize; - err = VOP_BMAP(vp, vblock, NULL, &block, run, NULL); - - if (err || (block == -1)) - rtaddress = -1; - else { - rtaddress = block + voffset / DEV_BSIZE; + err = VOP_BMAP(vp, vblock, NULL, rtaddress, run, NULL); + if (err == 0) { + if (*rtaddress != -1) + *rtaddress += voffset / DEV_BSIZE; if (run) { *run += 1; *run *= bsize/PAGE_SIZE; @@ -473,7 +467,7 @@ vnode_pager_addr(vp, address, run) } } - return rtaddress; + return (err); } /* @@ -513,7 +507,9 @@ vnode_pager_input_smlfs(object, m) if (address >= object->un_pager.vnp.vnp_size) { fileaddr = -1; } else { - fileaddr = vnode_pager_addr(vp, address, NULL); + error = vnode_pager_addr(vp, address, &fileaddr, NULL); + if (error) + break; } if (fileaddr != -1) { bp = getpbuf(&vnode_pbuf_freecnt); @@ -804,8 +800,17 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage) * calculate the run that includes the required page */ for (first = 0, i = 0; i < count; i = runend) { - firstaddr = vnode_pager_addr(vp, - IDX_TO_OFF(m[i]->pindex), &runpg); + if (vnode_pager_addr(vp, IDX_TO_OFF(m[i]->pindex), &firstaddr, + &runpg) != 0) { + VM_OBJECT_LOCK(object); + vm_page_lock_queues(); + for (; i < count; i++) + if (i != reqpage) + vm_page_free(m[i]); + vm_page_unlock_queues(); + VM_OBJECT_UNLOCK(object); + return (VM_PAGER_ERROR); + } if (firstaddr == -1) { VM_OBJECT_LOCK(object); if (i == reqpage && foff < object->un_pager.vnp.vnp_size) {