summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2002-06-22 19:09:35 +0000
committerdillon <dillon@FreeBSD.org>2002-06-22 19:09:35 +0000
commit0af4a7d8da66dacf1d307fa01b5bd13241d44aec (patch)
treecd065d642a360b51aa06012c167cce0c207595b1 /sys/kern/vfs_bio.c
parent411b7ea1b56bfd191313a2901c491f6f665c4282 (diff)
downloadFreeBSD-src-0af4a7d8da66dacf1d307fa01b5bd13241d44aec.zip
FreeBSD-src-0af4a7d8da66dacf1d307fa01b5bd13241d44aec.tar.gz
Fix a bug in vfs_bio_clrbuf(). The single-page-clrbuf optimization was
improperly clearing more then just the invalid portions of the page. (This bug is not known to have been triggered by anything). Submitted by: tegge MFC after: 7 days
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r--sys/kern/vfs_bio.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 100aebf..ab19f82 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -3224,7 +3224,8 @@ vfs_bio_set_validclean(struct buf *bp, int base, int size)
*/
void
-vfs_bio_clrbuf(struct buf *bp) {
+vfs_bio_clrbuf(struct buf *bp)
+{
int i, mask = 0;
caddr_t sa, ea;
@@ -3236,13 +3237,17 @@ vfs_bio_clrbuf(struct buf *bp) {
if( (bp->b_npages == 1) && (bp->b_bufsize < PAGE_SIZE) &&
(bp->b_offset & PAGE_MASK) == 0) {
mask = (1 << (bp->b_bufsize / DEV_BSIZE)) - 1;
+ if ((bp->b_pages[0]->valid & mask) == mask) {
+ bp->b_resid = 0;
+ return;
+ }
if (((bp->b_pages[0]->flags & PG_ZERO) == 0) &&
- ((bp->b_pages[0]->valid & mask) != mask)) {
+ ((bp->b_pages[0]->valid & mask) == 0)) {
bzero(bp->b_data, bp->b_bufsize);
+ bp->b_pages[0]->valid |= mask;
+ bp->b_resid = 0;
+ return;
}
- bp->b_pages[0]->valid |= mask;
- bp->b_resid = 0;
- return;
}
ea = sa = bp->b_data;
for(i=0;i<bp->b_npages;i++,sa=ea) {
OpenPOWER on IntegriCloud