diff options
author | peadar <peadar@FreeBSD.org> | 2004-07-06 23:40:40 +0000 |
---|---|---|
committer | peadar <peadar@FreeBSD.org> | 2004-07-06 23:40:40 +0000 |
commit | adb7022709c5fecd627eb2ac49abcb93b838d94b (patch) | |
tree | 890ae6291c5a6aee8ed7e05b8164194206191baa /sys/kern/vfs_bio.c | |
parent | 075809bebd3a385c71033f2be25c423d68f13f6b (diff) | |
download | FreeBSD-src-adb7022709c5fecd627eb2ac49abcb93b838d94b.zip FreeBSD-src-adb7022709c5fecd627eb2ac49abcb93b838d94b.tar.gz |
Fix bug introduced in rev 1.434:
When avoiding the zeroing of "bogus_page" when it appears in a buf,
be sure to advance the pointers into the data for successive pages.
The bug caused file corruption when read(2)ing from a "hole" in a
file where a previous page of the read block had already been faulted
in: fsx tripped up on this pretty quickly. The particular access
pattern is probably pretty unusual, so other applications probably
wouldn't have had problems, but you'd never know.
Reviewed By: alc@
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r-- | sys/kern/vfs_bio.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index ba939fe..bff9c21 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -3553,13 +3553,13 @@ vfs_bio_clrbuf(struct buf *bp) } ea = sa = bp->b_data; for(i=0;i<bp->b_npages;i++,sa=ea) { - if (bp->b_pages[i] == bogus_page) - continue; - j = ((vm_offset_t)sa & PAGE_MASK) / DEV_BSIZE; ea = (caddr_t)trunc_page((vm_offset_t)sa + PAGE_SIZE); ea = (caddr_t)(vm_offset_t)ulmin( (u_long)(vm_offset_t)ea, (u_long)(vm_offset_t)bp->b_data + bp->b_bufsize); + if (bp->b_pages[i] == bogus_page) + continue; + j = ((vm_offset_t)sa & PAGE_MASK) / DEV_BSIZE; mask = ((1 << ((ea - sa) / DEV_BSIZE)) - 1) << j; VM_OBJECT_LOCK_ASSERT(bp->b_pages[i]->object, MA_OWNED); if ((bp->b_pages[i]->valid & mask) == mask) |