FreeBSD/sys/kern/vfs_bio.c
/*
 * Perform page invalidation when a buffer is released.  The fully invalid
 * pages will be reclaimed later in vfs_vmio_truncate().
 */
Perform page invalidation when a buffer is released.  The fully invalid
pages will be reclaimed later in vfs_vmio_truncate().
Perform page invalidation when a buffer is released . The fully invalid pages will be reclaimed later in vfs_vmio_truncate () .
static void
vfs_vmio_invalidate(struct buf *bp)
{
	vm_object_t obj;
	vm_page_t m;
	int i, resid, poffset, presid;
	if (buf_mapped(bp)) {
		BUF_CHECK_MAPPED(bp);
		pmap_qremove(trunc_page((vm_offset_t)bp->b_data), bp->b_npages);
	} else
		BUF_CHECK_UNMAPPED(bp);
	obj = bp->b_bufobj->bo_object;
	resid = bp->b_bufsize;
	poffset = bp->b_offset & PAGE_MASK;
	VM_OBJECT_WLOCK(obj);
	for (i = 0; i < bp->b_npages; i++) {
		m = bp->b_pages[i];
		if (m == bogus_page)
			panic("vfs_vmio_invalidate: Unexpected bogus page.");
		bp->b_pages[i] = NULL;
		presid = resid > (PAGE_SIZE - poffset) ?
		    (PAGE_SIZE - poffset) : resid;
		KASSERT(presid >= 0, ("brelse: extra page"));
		while (vm_page_xbusied(m)) {
			vm_page_lock(m);
			VM_OBJECT_WUNLOCK(obj);
			vm_page_busy_sleep(m, "mbncsh");
			VM_OBJECT_WLOCK(obj);
		}
		if (pmap_page_wired_mappings(m) == 0)
			vm_page_set_invalid(m, poffset, presid);
		vfs_vmio_unwire(bp, m);
		resid -= presid;
		poffset = 0;
	}
	VM_OBJECT_WUNLOCK(obj);
	bp->b_npages = 0;
}
static void vfs_vmio_invalidate ( struct buf * bp ) { vm_object_t obj ; vm_page_t m ; int i , resid , poffset , presid ; if ( buf_mapped ( bp ) ) { BUF_CHECK_MAPPED ( bp ) ; pmap_qremove ( trunc_page ( ( vm_offset_t ) bp -> b_data ) , bp -> b_npages ) ; } else BUF_CHECK_UNMAPPED ( bp ) ; obj = bp -> b_bufobj -> bo_object ; resid = bp -> b_bufsize ; poffset = bp -> b_offset & PAGE_MASK ; VM_OBJECT_WLOCK ( obj ) ; for ( i = 0 ; i < bp -> b_npages ; i ++ ) { m = bp -> b_pages [ i ] ; if ( m == bogus_page ) panic ( " " ) ; bp -> b_pages [ i ] = NULL ; presid = resid > ( PAGE_SIZE - poffset ) ? ( PAGE_SIZE - poffset ) : resid ; KASSERT ( presid >= 0 , ( " " ) ) ; while ( vm_page_xbusied ( m ) ) { vm_page_lock ( m ) ; VM_OBJECT_WUNLOCK ( obj ) ; vm_page_busy_sleep ( m , " " ) ; VM_OBJECT_WLOCK ( obj ) ; } if ( pmap_page_wired_mappings ( m ) == 0 ) vm_page_set_invalid ( m , poffset , presid ) ; vfs_vmio_unwire ( bp , m ) ; resid -= presid ; poffset = 0 ; } VM_OBJECT_WUNLOCK ( obj ) ; bp -> b_npages = 0 ; }
Perform page invalidation when a buffer is released.
Perform page invalidation when a buffer is released .
/*
	 * Get the base offset and length of the buffer.  Note that 
	 * in the VMIO case if the buffer block size is not
	 * page-aligned then b_data pointer may not be page-aligned.
	 * But our b_pages[] array *IS* page aligned.
	 *
	 * block sizes less then DEV_BSIZE (usually 512) are not 
	 * supported due to the page granularity bits (m->valid,
	 * m->dirty, etc...). 
	 *
	 * See man buf(9) for more information
	 */