FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
/*
 * When a file is memory mapped, we must keep the IO data synchronized
 * between the DMU cache and the memory mapped pages.  What this means:
 *
 * On Read:	We "read" preferentially from memory mapped pages,
 *		else we default from the dmu buffer.
 *
 * NOTE: We will always "break up" the IO into PAGESIZE uiomoves when
 *	 the file is memory mapped.
 */
When a file is memory mapped, we must keep the IO data synchronized
between the DMU cache and the memory mapped pages.  What this means.

On Read:     We "read" preferentially from memory mapped pages,
else we default from the dmu buffer.

We will always "break up" the IO into PAGESIZE uiomoves when
the file is memory mapped.
When a file is memory mapped we must keep the IO data synchronized between the DMU cache and the memory mapped pages . What this means . On Read : We " read " preferentially from memory mapped pages else we default from the dmu buffer . We will always " break up " the IO into PAGESIZE uiomoves when the file is memory mapped .
static int
mappedread(vnode_t *vp, int nbytes, uio_t *uio)
{
	znode_t *zp = VTOZ(vp);
	vm_object_t obj;
	int64_t start;
	caddr_t va;
	int len = nbytes;
	int off;
	int error = 0;
	ASSERT(vp->v_mount != NULL);
	obj = vp->v_object;
	ASSERT(obj != NULL);
	start = uio->uio_loffset;
	off = start & PAGEOFFSET;
	zfs_vmobject_wlock(obj);
	for (start &= PAGEMASK; len > 0; start += PAGESIZE) {
		vm_page_t pp;
		uint64_t bytes = MIN(PAGESIZE - off, len);
		if (pp = page_hold(vp, start)) {
			struct sf_buf *sf;
			caddr_t va;
			zfs_vmobject_wunlock(obj);
			va = zfs_map_page(pp, &sf);
#ifdef illumos
			error = uiomove(va + off, bytes, UIO_READ, uio);
#else
			error = vn_io_fault_uiomove(va + off, bytes, uio);
#endif
			zfs_unmap_page(sf);
			zfs_vmobject_wlock(obj);
			page_unhold(pp);
		} else {
			zfs_vmobject_wunlock(obj);
			error = dmu_read_uio_dbuf(sa_get_db(zp->z_sa_hdl),
			    uio, bytes);
			zfs_vmobject_wlock(obj);
		}
		len -= bytes;
		off = 0;
		if (error)
			break;
	}
	zfs_vmobject_wunlock(obj);
	return (error);
}
static int mappedread ( vnode_t * vp , int nbytes , uio_t * uio ) { znode_t * zp = VTOZ ( vp ) ; vm_object_t obj ; int64_t start ; caddr_t va ; int len = nbytes ; int off ; int error = 0 ; ASSERT ( vp -> v_mount != NULL ) ; obj = vp -> v_object ; ASSERT ( obj != NULL ) ; start = uio -> uio_loffset ; off = start & PAGEOFFSET ; zfs_vmobject_wlock ( obj ) ; for ( start &= PAGEMASK ; len > 0 ; start += PAGESIZE ) { vm_page_t pp ; uint64_t bytes = MIN ( PAGESIZE - off , len ) ; if ( pp = page_hold ( vp , start ) ) { struct sf_buf * sf ; caddr_t va ; zfs_vmobject_wunlock ( obj ) ; va = zfs_map_page ( pp , & sf ) ; #ifdef illumos error = uiomove ( va + off , bytes , UIO_READ , uio ) ; #else error = vn_io_fault_uiomove ( va + off , bytes , uio ) ; #endif zfs_unmap_page ( sf ) ; zfs_vmobject_wlock ( obj ) ; page_unhold ( pp ) ; } else { zfs_vmobject_wunlock ( obj ) ; error = dmu_read_uio_dbuf ( sa_get_db ( zp -> z_sa_hdl ) , uio , bytes ) ; zfs_vmobject_wlock ( obj ) ; } len -= bytes ; off = 0 ; if ( error ) break ; } zfs_vmobject_wunlock ( obj ) ; return ( error ) ; }
When a file is memory mapped, we must keep the IO data synchronized
 between the DMU cache and the memory mapped pages.
When a file is memory mapped we must keep the IO data synchronized between the DMU cache and the memory mapped pages .