summaryrefslogtreecommitdiffstats
path: root/sys/vm/vnode_pager.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1999-04-05 19:38:30 +0000
committerjulian <julian@FreeBSD.org>1999-04-05 19:38:30 +0000
commit0ed09d2ad576c0a64797f8ca9bebd32873f770ae (patch)
tree6de1ee6b7f198b11b20d471fbc1a36de8329d82e /sys/vm/vnode_pager.c
parent9ac433dd352fdfe7f3038aa0e1a4333686bc07fc (diff)
downloadFreeBSD-src-0ed09d2ad576c0a64797f8ca9bebd32873f770ae.zip
FreeBSD-src-0ed09d2ad576c0a64797f8ca9bebd32873f770ae.tar.gz
Catch a case spotted by Tor where files mmapped could leave garbage in the
unallocated parts of the last page when the file ended on a frag but not a page boundary. Delimitted by tags PRE_MATT_MMAP_EOF and POST_MATT_MMAP_EOF, in files alpha/alpha/pmap.c i386/i386/pmap.c nfs/nfs_bio.c vm/pmap.h vm/vm_page.c vm/vm_page.h vm/vnode_pager.c miscfs/specfs/spec_vnops.c ufs/ufs/ufs_readwrite.c kern/vfs_bio.c Submitted by: Matt Dillon <dillon@freebsd.org> Reviewed by: Alan Cox <alc@freebsd.org>
Diffstat (limited to 'sys/vm/vnode_pager.c')
-rw-r--r--sys/vm/vnode_pager.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index b645ee3..39f1c35 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
- * $Id: vnode_pager.c,v 1.104 1999/02/27 23:39:28 alc Exp $
+ * $Id: vnode_pager.c,v 1.105 1999/03/27 02:39:01 eivind Exp $
*/
/*
@@ -624,23 +624,21 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
cnt.v_vnodepgsin++;
return vnode_pager_input_smlfs(object, m[reqpage]);
}
+
/*
- * if ANY DEV_BSIZE blocks are valid on a large filesystem block
- * then, the entire page is valid --
- * XXX no it isn't
+ * If we have a completely valid page available to us, we can
+ * clean up and return. Otherwise we have to re-read the
+ * media.
*/
- if (m[reqpage]->valid != VM_PAGE_BITS_ALL)
- m[reqpage]->valid = 0;
-
- if (m[reqpage]->valid) {
- m[reqpage]->valid = VM_PAGE_BITS_ALL;
+ if (m[reqpage]->valid == VM_PAGE_BITS_ALL) {
for (i = 0; i < count; i++) {
if (i != reqpage)
vnode_pager_freepage(m[i]);
}
return VM_PAGER_OK;
}
+ m[reqpage]->valid = 0;
/*
* here on direct device I/O
@@ -773,12 +771,25 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
mt = m[i];
if (nextoff <= size) {
+ /*
+ * Read filled up entire page.
+ */
mt->valid = VM_PAGE_BITS_ALL;
mt->dirty = 0;
pmap_clear_modify(VM_PAGE_TO_PHYS(mt));
} else {
- int nvalid = ((size + DEV_BSIZE - 1) - tfoff) & ~(DEV_BSIZE - 1);
- vm_page_set_validclean(mt, 0, nvalid);
+ /*
+ * Read did not fill up entire page. Since this
+ * is getpages, the page may be mapped, so we have
+ * to zero the invalid portions of the page even
+ * though we aren't setting them valid.
+ *
+ * Currently we do not set the entire page valid,
+ * we just try to clear the piece that we couldn't
+ * read.
+ */
+ vm_page_set_validclean(mt, 0, size - tfoff);
+ vm_page_zero_invalid(mt, FALSE);
}
vm_page_flag_clear(mt, PG_ZERO);
OpenPOWER on IntegriCloud