summaryrefslogtreecommitdiffstats
path: root/sys/ufs
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/ufs
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/ufs')
-rw-r--r--sys/ufs/ufs/ufs_readwrite.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c
index 368608b..d12a802 100644
--- a/sys/ufs/ufs/ufs_readwrite.c
+++ b/sys/ufs/ufs/ufs_readwrite.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_readwrite.c 8.11 (Berkeley) 5/8/95
- * $Id: ufs_readwrite.c,v 1.56 1999/01/21 08:29:09 dillon Exp $
+ * $Id: ufs_readwrite.c,v 1.57 1999/01/28 00:57:56 dillon Exp $
*/
#define BLKSIZE(a, b, c) blksize(a, b, c)
@@ -189,6 +189,13 @@ READ(ap)
lbn = lblkno(fs, uio->uio_offset);
nextlbn = lbn + 1;
+
+ /*
+ * size of buffer. The buffer representing the
+ * end of the file is rounded up to the size of
+ * the block type ( fragment or full block,
+ * depending ).
+ */
size = BLKSIZE(fs, ip, lbn);
blkoffset = blkoff(fs, uio->uio_offset);
@@ -536,11 +543,14 @@ ffs_getpages(ap)
firstindex = ap->a_m[0]->pindex;
/*
- * if ANY DEV_BSIZE blocks are valid on a large filesystem block
- * then, the entire page is valid --
+ * if ANY DEV_BSIZE blocks are valid on a large filesystem block,
+ * then the entire page is valid. Since the page may be mapped,
+ * user programs might reference data beyond the actual end of file
+ * occuring within the page. We have to zero that data.
*/
if (mreq->valid) {
- mreq->valid = VM_PAGE_BITS_ALL;
+ if (mreq->valid != VM_PAGE_BITS_ALL)
+ vm_page_zero_invalid(mreq, TRUE);
for (i = 0; i < pcount; i++) {
if (i != ap->a_reqpage) {
vm_page_free(ap->a_m[i]);
@@ -568,6 +578,7 @@ ffs_getpages(ap)
(firstindex != 0) && (firstindex <= vp->v_lastr) &&
((firstindex + pcount) > vp->v_lastr)) ||
(obj->behavior == OBJ_SEQUENTIAL)) {
+
struct uio auio;
struct iovec aiov;
int error;
@@ -620,8 +631,8 @@ ffs_getpages(ap)
if (mreq->valid == 0)
return VM_PAGER_ERROR;
-
- mreq->valid = VM_PAGE_BITS_ALL;
+ if (mreq->valid != VM_PAGE_BITS_ALL)
+ vm_page_zero_invalid(mreq, TRUE);
return VM_PAGER_OK;
}
OpenPOWER on IntegriCloud