diff options
author | alc <alc@FreeBSD.org> | 2006-10-08 20:26:16 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2006-10-08 20:26:16 +0000 |
commit | bd713f224f205afa56abb4df2f13b114002cb621 (patch) | |
tree | 3ec2cb30028fcbc3a2ed154b4b3b5aa4740612d8 /sys/vm | |
parent | 704cc3b17d12cebe2a6334b1a083f42c74350fde (diff) | |
download | FreeBSD-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.c | 15 |
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); |