FreeBSD/sys/kern/vfs_bio.c
/*
 * This routine is called before a device strategy routine.
 * It is used to tell the VM system that paging I/O is in
 * progress, and treat the pages associated with the buffer
 * almost as being exclusive busy.  Also the object paging_in_progress
 * flag is handled to make sure that the object doesn't become
 * inconsistent.
 *
 * Since I/O has not been initiated yet, certain buffer flags
 * such as BIO_ERROR or B_INVAL may be in an inconsistent state
 * and should be ignored.
 */
This routine is called before a device strategy routine.
It is used to tell the VM system that paging I/O is in
progress, and treat the pages associated with the buffer
almost as being exclusive busy.  Also the object paging_in_progress
flag is handled to make sure that the object doesn't become
inconsistent.

Since I/O has not been initiated yet, certain buffer flags
such as BIO_ERROR or B_INVAL may be in an inconsistent state
and should be ignored.
This routine is called before a device strategy routine . It is used to tell the VM system that paging I / O is in progress and treat the pages associated with the buffer almost as being exclusive busy . Also the object paging_in_progress flag is handled to make sure that the object doesn ' t become inconsistent . Since I / O has not been initiated yet certain buffer flags such as BIO_ERROR or B_INVAL may be in an inconsistent state and should be ignored .
void
vfs_busy_pages(struct buf *bp, int clear_modify)
{
	int i, bogus;
	vm_object_t obj;
	vm_ooffset_t foff;
	vm_page_t m;
	if (!(bp->b_flags & B_VMIO))
		return;
	obj = bp->b_bufobj->bo_object;
	foff = bp->b_offset;
	KASSERT(bp->b_offset != NOOFFSET,
	    ("vfs_busy_pages: no buffer offset"));
	VM_OBJECT_WLOCK(obj);
	vfs_drain_busy_pages(bp);
	if (bp->b_bufsize != 0)
		vfs_setdirty_locked_object(bp);
	bogus = 0;
	for (i = 0; i < bp->b_npages; i++) {
		m = bp->b_pages[i];
		if ((bp->b_flags & B_CLUSTER) == 0) {
			vm_object_pip_add(obj, 1);
			vm_page_sbusy(m);
		}
		if (clear_modify) {
			pmap_remove_write(m);
			vfs_page_set_validclean(bp, foff, m);
		} else if (m->valid == VM_PAGE_BITS_ALL &&
		    (bp->b_flags & B_CACHE) == 0) {
			bp->b_pages[i] = bogus_page;
			bogus++;
		}
		foff = (foff + PAGE_SIZE) & ~(off_t)PAGE_MASK;
	}
	VM_OBJECT_WUNLOCK(obj);
	if (bogus && buf_mapped(bp)) {
		BUF_CHECK_MAPPED(bp);
		pmap_qenter(trunc_page((vm_offset_t)bp->b_data),
		    bp->b_pages, bp->b_npages);
	}
}
void vfs_busy_pages ( struct buf * bp , int clear_modify ) { int i , bogus ; vm_object_t obj ; vm_ooffset_t foff ; vm_page_t m ; if ( ! ( bp -> b_flags & B_VMIO ) ) return ; obj = bp -> b_bufobj -> bo_object ; foff = bp -> b_offset ; KASSERT ( bp -> b_offset != NOOFFSET , ( " " ) ) ; VM_OBJECT_WLOCK ( obj ) ; vfs_drain_busy_pages ( bp ) ; if ( bp -> b_bufsize != 0 ) vfs_setdirty_locked_object ( bp ) ; bogus = 0 ; for ( i = 0 ; i < bp -> b_npages ; i ++ ) { m = bp -> b_pages [ i ] ; if ( ( bp -> b_flags & B_CLUSTER ) == 0 ) { vm_object_pip_add ( obj , 1 ) ; vm_page_sbusy ( m ) ; } if ( clear_modify ) { pmap_remove_write ( m ) ; vfs_page_set_validclean ( bp , foff , m ) ; } else if ( m -> valid == VM_PAGE_BITS_ALL && ( bp -> b_flags & B_CACHE ) == 0 ) { bp -> b_pages [ i ] = bogus_page ; bogus ++ ; } foff = ( foff + PAGE_SIZE ) & ~ ( off_t ) PAGE_MASK ; } VM_OBJECT_WUNLOCK ( obj ) ; if ( bogus && buf_mapped ( bp ) ) { BUF_CHECK_MAPPED ( bp ) ; pmap_qenter ( trunc_page ( ( vm_offset_t ) bp -> b_data ) , bp -> b_pages , bp -> b_npages ) ; } }
This routine is called before a device strategy routine.
This routine is called before a device strategy routine .
/*
		 * When readying a buffer for a read ( i.e
		 * clear_modify == 0 ), it is important to do
		 * bogus_page replacement for valid pages in 
		 * partially instantiated buffers.  Partially 
		 * instantiated buffers can, in turn, occur when
		 * reconstituting a buffer from its VM backing store
		 * base.  We only have to do this if B_CACHE is
		 * clear ( which causes the I/O to occur in the
		 * first place ).  The replacement prevents the read
		 * I/O from overwriting potentially dirty VM-backed
		 * pages.  XXX bogus page replacement is, uh, bogus.
		 * It may not work properly with small-block devices.
		 * We need to find a better way.
		 */