diff options
author | dillon <dillon@FreeBSD.org> | 2002-06-22 19:09:35 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2002-06-22 19:09:35 +0000 |
commit | 0af4a7d8da66dacf1d307fa01b5bd13241d44aec (patch) | |
tree | cd065d642a360b51aa06012c167cce0c207595b1 /sys/kern/vfs_bio.c | |
parent | 411b7ea1b56bfd191313a2901c491f6f665c4282 (diff) | |
download | FreeBSD-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.c | 15 |
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) { |