diff options
author | julian <julian@FreeBSD.org> | 1999-04-05 19:38:30 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 1999-04-05 19:38:30 +0000 |
commit | 0ed09d2ad576c0a64797f8ca9bebd32873f770ae (patch) | |
tree | 6de1ee6b7f198b11b20d471fbc1a36de8329d82e /sys/ufs | |
parent | 9ac433dd352fdfe7f3038aa0e1a4333686bc07fc (diff) | |
download | FreeBSD-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.c | 23 |
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; } |