FreeBSD/sys/kern/vfs_bio.c
/*
 *	vfs_bio_clrbuf:
 *
 *	If the specified buffer is a non-VMIO buffer, clear the entire
 *	buffer.  If the specified buffer is a VMIO buffer, clear and
 *	validate only the previously invalid portions of the buffer.
 *	This routine essentially fakes an I/O, so we need to clear
 *	BIO_ERROR and B_INVAL.
 *
 *	Note that while we only theoretically need to clear through b_bcount,
 *	we go ahead and clear through b_bufsize.
 */
If the specified buffer is a non-VMIO buffer, clear the entire
buffer.  If the specified buffer is a VMIO buffer, clear and
validate only the previously invalid portions of the buffer.
This routine essentially fakes an I/O, so we need to clear
BIO_ERROR and B_INVAL.

Note that while we only theoretically need to clear through b_bcount,
we go ahead and clear through b_bufsize.
If the specified buffer is a non - VMIO buffer clear the entire buffer . If the specified buffer is a VMIO buffer clear and validate only the previously invalid portions of the buffer . This routine essentially fakes an I / O so we need to clear BIO_ERROR and B_INVAL . Note that while we only theoretically need to clear through b_bcount we go ahead and clear through b_bufsize .
void
vfs_bio_clrbuf(struct buf *bp) 
{
	int i, j, mask, sa, ea, slide;
	if ((bp->b_flags & (B_VMIO | B_MALLOC)) != B_VMIO) {
		clrbuf(bp);
		return;
	}
	bp->b_flags &= ~B_INVAL;
	bp->b_ioflags &= ~BIO_ERROR;
	VM_OBJECT_WLOCK(bp->b_bufobj->bo_object);
	if ((bp->b_npages == 1) && (bp->b_bufsize < PAGE_SIZE) &&
	    (bp->b_offset & PAGE_MASK) == 0) {
		if (bp->b_pages[0] == bogus_page)
			goto unlock;
		mask = (1 << (bp->b_bufsize / DEV_BSIZE)) - 1;
		VM_OBJECT_ASSERT_WLOCKED(bp->b_pages[0]->object);
		if ((bp->b_pages[0]->valid & mask) == mask)
			goto unlock;
		if ((bp->b_pages[0]->valid & mask) == 0) {
			pmap_zero_page_area(bp->b_pages[0], 0, bp->b_bufsize);
			bp->b_pages[0]->valid |= mask;
			goto unlock;
		}
	}
	sa = bp->b_offset & PAGE_MASK;
	slide = 0;
	for (i = 0; i < bp->b_npages; i++, sa = 0) {
		slide = imin(slide + PAGE_SIZE, bp->b_offset + bp->b_bufsize);
		ea = slide & PAGE_MASK;
		if (ea == 0)
			ea = PAGE_SIZE;
		if (bp->b_pages[i] == bogus_page)
			continue;
		j = sa / DEV_BSIZE;
		mask = ((1 << ((ea - sa) / DEV_BSIZE)) - 1) << j;
		VM_OBJECT_ASSERT_WLOCKED(bp->b_pages[i]->object);
		if ((bp->b_pages[i]->valid & mask) == mask)
			continue;
		if ((bp->b_pages[i]->valid & mask) == 0)
			pmap_zero_page_area(bp->b_pages[i], sa, ea - sa);
		else {
			for (; sa < ea; sa += DEV_BSIZE, j++) {
				if ((bp->b_pages[i]->valid & (1 << j)) == 0) {
					pmap_zero_page_area(bp->b_pages[i],
					    sa, DEV_BSIZE);
				}
			}
		}
		bp->b_pages[i]->valid |= mask;
	}
unlock:
	VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object);
	bp->b_resid = 0;
}
void vfs_bio_clrbuf ( struct buf * bp ) { int i , j , mask , sa , ea , slide ; if ( ( bp -> b_flags & ( B_VMIO | B_MALLOC ) ) != B_VMIO ) { clrbuf ( bp ) ; return ; } bp -> b_flags &= ~ B_INVAL ; bp -> b_ioflags &= ~ BIO_ERROR ; VM_OBJECT_WLOCK ( bp -> b_bufobj -> bo_object ) ; if ( ( bp -> b_npages == 1 ) && ( bp -> b_bufsize < PAGE_SIZE ) && ( bp -> b_offset & PAGE_MASK ) == 0 ) { if ( bp -> b_pages [ 0 ] == bogus_page ) goto unlock ; mask = ( 1 << ( bp -> b_bufsize / DEV_BSIZE ) ) - 1 ; VM_OBJECT_ASSERT_WLOCKED ( bp -> b_pages [ 0 ] -> object ) ; if ( ( bp -> b_pages [ 0 ] -> valid & mask ) == mask ) goto unlock ; if ( ( bp -> b_pages [ 0 ] -> valid & mask ) == 0 ) { pmap_zero_page_area ( bp -> b_pages [ 0 ] , 0 , bp -> b_bufsize ) ; bp -> b_pages [ 0 ] -> valid |= mask ; goto unlock ; } } sa = bp -> b_offset & PAGE_MASK ; slide = 0 ; for ( i = 0 ; i < bp -> b_npages ; i ++ , sa = 0 ) { slide = imin ( slide + PAGE_SIZE , bp -> b_offset + bp -> b_bufsize ) ; ea = slide & PAGE_MASK ; if ( ea == 0 ) ea = PAGE_SIZE ; if ( bp -> b_pages [ i ] == bogus_page ) continue ; j = sa / DEV_BSIZE ; mask = ( ( 1 << ( ( ea - sa ) / DEV_BSIZE ) ) - 1 ) << j ; VM_OBJECT_ASSERT_WLOCKED ( bp -> b_pages [ i ] -> object ) ; if ( ( bp -> b_pages [ i ] -> valid & mask ) == mask ) continue ; if ( ( bp -> b_pages [ i ] -> valid & mask ) == 0 ) pmap_zero_page_area ( bp -> b_pages [ i ] , sa , ea - sa ) ; else { for ( ; sa < ea ; sa += DEV_BSIZE , j ++ ) { if ( ( bp -> b_pages [ i ] -> valid & ( 1 << j ) ) == 0 ) { pmap_zero_page_area ( bp -> b_pages [ i ] , sa , DEV_BSIZE ) ; } } } bp -> b_pages [ i ] -> valid |= mask ; } unlock : VM_OBJECT_WUNLOCK ( bp -> b_bufobj -> bo_object ) ; bp -> b_resid = 0 ; }
vfs_bio_clrbuf:
      If the specified buffer is a non-VMIO buffer, clear the entire
      buffer.
vfs_bio_clrbuf : If the specified buffer is a non - VMIO buffer clear the entire buffer .