summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2006-10-08 20:26:16 +0000
committeralc <alc@FreeBSD.org>2006-10-08 20:26:16 +0000
commitbd713f224f205afa56abb4df2f13b114002cb621 (patch)
tree3ec2cb30028fcbc3a2ed154b4b3b5aa4740612d8 /sys/vm
parent704cc3b17d12cebe2a6334b1a083f42c74350fde (diff)
downloadFreeBSD-src-bd713f224f205afa56abb4df2f13b114002cb621.zip
FreeBSD-src-bd713f224f205afa56abb4df2f13b114002cb621.tar.gz
Change vnode_pager_generic_getpages() so that it does not panic if the
given file is sparse. Instead, it zeroes the requested page. Reviewed by: tegge PR: kern/98116 MFC after: 3 days
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vnode_pager.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index a8f9912..e683a84 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -695,7 +695,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
vm_offset_t kva;
off_t foff, tfoff, nextoff;
int i, j, size, bsize, first;
- daddr_t firstaddr;
+ daddr_t firstaddr, reqblock;
struct bufobj *bo;
int runpg;
int runend;
@@ -724,7 +724,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
/*
* if we can't bmap, use old VOP code
*/
- if (VOP_BMAP(vp, 0, &bo, 0, NULL, NULL)) {
+ if (VOP_BMAP(vp, foff / bsize, &bo, &reqblock, NULL, NULL)) {
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
for (i = 0; i < count; i++)
@@ -770,6 +770,17 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
return VM_PAGER_OK;
+ } else if (reqblock == -1) {
+ pmap_zero_page(m[reqpage]);
+ vm_page_undirty(m[reqpage]);
+ m[reqpage]->valid = VM_PAGE_BITS_ALL;
+ vm_page_lock_queues();
+ for (i = 0; i < count; i++)
+ if (i != reqpage)
+ vm_page_free(m[i]);
+ vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(object);
+ return (VM_PAGER_OK);
}
m[reqpage]->valid = 0;
VM_OBJECT_UNLOCK(object);
OpenPOWER on IntegriCloud