コード例 #1
0
ファイル: vnode_pager.c プロジェクト: kwitaszczyk/freebsd
int
vnode_pager_local_getpages_async(struct vop_getpages_async_args *ap)
{

	return (vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count,
	    ap->a_rbehind, ap->a_rahead, ap->a_iodone, ap->a_arg));
}
コード例 #2
0
ファイル: vnode_pager.c プロジェクト: kwitaszczyk/freebsd
/*
 * The implementation of VOP_GETPAGES() and VOP_GETPAGES_ASYNC() for
 * local filesystems, where partially valid pages can only occur at
 * the end of file.
 */
int
vnode_pager_local_getpages(struct vop_getpages_args *ap)
{

	return (vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count,
	    ap->a_rbehind, ap->a_rahead, NULL, NULL));
}
コード例 #3
0
static int
vnode_pager_local_getpages0(struct vnode *vp, vm_page_t *m, int bytecount,
    int reqpage, vop_getpages_iodone_t iodone, void *arg)
{
	vm_page_t mreq;

	mreq = m[reqpage];

	/*
	 * Since the caller has busied the requested page, that page's valid
	 * field will not be changed by other threads.
	 */
	vm_page_assert_xbusied(mreq);

	/*
	 * The requested page has valid blocks.  Invalid part can only
	 * exist at the end of file, and the page is made fully valid
	 * by zeroing in vm_pager_get_pages().  Free non-requested
	 * pages, since no i/o is done to read its content.
	 */
	if (mreq->valid != 0) {
		vm_pager_free_nonreq(mreq->object, m, reqpage,
		    round_page(bytecount) / PAGE_SIZE, FALSE);
		if (iodone != NULL)
			iodone(arg, m, reqpage, 0);
		return (VM_PAGER_OK);
	}

	return (vnode_pager_generic_getpages(vp, m, bytecount, reqpage,
	    iodone, arg));
}
コード例 #4
0
ファイル: union_vnops.c プロジェクト: AhmadTux/DragonFlyBSD
static int
union_getpages(struct vop_getpages_args *ap)
{
	int r;

	r = vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
					 ap->a_count, ap->a_reqpage,
					 ap->a_seqaccess);
	return(r);
}
コード例 #5
0
/*
 * Implement standard getpages and putpages.  All filesystems must use
 * the buffer cache to back regular files.
 */
int
vop_stdgetpages(struct vop_getpages_args *ap)
{
	struct mount *mp;
	int error;

	if ((mp = ap->a_vp->v_mount) != NULL) {
		error = vnode_pager_generic_getpages(
				ap->a_vp, ap->a_m, ap->a_count,
				ap->a_reqpage, ap->a_seqaccess);
	} else {
		error = VM_PAGER_BAD;
	}
	return (error);
}
コード例 #6
0
ファイル: nwfs_io.c プロジェクト: mihaicarabas/dragonfly
/*
 * Vnode op for VM getpages.
 * Wish wish .... get rid from multiple IO routines
 *
 * nwfs_getpages(struct vnode *a_vp, vm_page_t *a_m, int a_count,
 *		 int a_reqpage, vm_ooffset_t a_offset)
 */
int
nwfs_getpages(struct vop_getpages_args *ap)
{
#ifndef NWFS_RWCACHE
	return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count,
					    ap->a_reqpage, ap->a_seqaccess);
#else
	int i, error, npages;
	size_t nextoff, toff;
	size_t count;
	size_t size;
	struct uio uio;
	struct iovec iov;
	vm_offset_t kva;
	struct buf *bp;
	struct vnode *vp;
	struct thread *td = curthread;	/* XXX */
	struct ucred *cred;
	struct nwmount *nmp;
	struct nwnode *np;
	vm_page_t *pages;

	KKASSERT(td->td_proc);
	cred = td->td_proc->p_ucred;

	vp = ap->a_vp;
	np = VTONW(vp);
	nmp = VFSTONWFS(vp->v_mount);
	pages = ap->a_m;
	count = (size_t)ap->a_count;

	if (vp->v_object == NULL) {
		kprintf("nwfs_getpages: called with non-merged cache vnode??\n");
		return VM_PAGER_ERROR;
	}

	bp = getpbuf_kva(&nwfs_pbuf_freecnt);
	npages = btoc(count);
	kva = (vm_offset_t) bp->b_data;
	pmap_qenter(kva, pages, npages);

	iov.iov_base = (caddr_t) kva;
	iov.iov_len = count;
	uio.uio_iov = &iov;
	uio.uio_iovcnt = 1;
	uio.uio_offset = IDX_TO_OFF(pages[0]->pindex);
	uio.uio_resid = count;
	uio.uio_segflg = UIO_SYSSPACE;
	uio.uio_rw = UIO_READ;
	uio.uio_td = td;

	error = ncp_read(NWFSTOCONN(nmp), &np->n_fh, &uio,cred);
	pmap_qremove(kva, npages);

	relpbuf(bp, &nwfs_pbuf_freecnt);

	if (error && (uio.uio_resid == count)) {
		kprintf("nwfs_getpages: error %d\n",error);
		for (i = 0; i < npages; i++) {
			if (ap->a_reqpage != i)
				vnode_pager_freepage(pages[i]);
		}
		return VM_PAGER_ERROR;
	}

	size = count - uio.uio_resid;

	for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
		vm_page_t m;
		nextoff = toff + PAGE_SIZE;
		m = pages[i];

		m->flags &= ~PG_ZERO;

		/*
		 * NOTE: pmap dirty bit should have already been cleared.
		 *	 We do not clear it here.
		 */
		if (nextoff <= size) {
			m->valid = VM_PAGE_BITS_ALL;
			m->dirty = 0;
		} else {
			int nvalid = ((size + DEV_BSIZE - 1) - toff) &
				      ~(DEV_BSIZE - 1);
			vm_page_set_validclean(m, 0, nvalid);
		}
		
		if (i != ap->a_reqpage) {
			/*
			 * Whether or not to leave the page activated is up in
			 * the air, but we should put the page on a page queue
			 * somewhere (it already is in the object).  Result:
			 * It appears that emperical results show that
			 * deactivating pages is best.
			 */

			/*
			 * Just in case someone was asking for this page we
			 * now tell them that it is ok to use.
			 */
			if (!error) {
				if (m->flags & PG_REFERENCED)
					vm_page_activate(m);
				else
					vm_page_deactivate(m);
				vm_page_wakeup(m);
			} else {
				vnode_pager_freepage(m);
			}
		}
	}
	return 0;
#endif /* NWFS_RWCACHE */
}