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
This commit is contained in:
Alan Cox 2006-10-14 22:09:03 +00:00
parent fae6222bdb
commit bff763439b

View File

@ -75,8 +75,8 @@ __FBSDID("$FreeBSD$");
#include <vm/vnode_pager.h>
#include <vm/vm_extern.h>
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) {