summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-09-19 08:14:55 +0000
committerphk <phk@FreeBSD.org>2004-09-19 08:14:55 +0000
commit73cf913d5f9c8b5932556b4f8630059a82fe0b22 (patch)
tree5b390f8ea232bc2f34d1fc7214e483cdd31abbd8 /sys/ufs
parent869702f330fe71fea7521b27b2b88095a0a70861 (diff)
downloadFreeBSD-src-73cf913d5f9c8b5932556b4f8630059a82fe0b22.zip
FreeBSD-src-73cf913d5f9c8b5932556b4f8630059a82fe0b22.tar.gz
The getpages VOP was a good stab at getting scatter/gather I/O without
too much kernel copying, but it is not the right way to do it, and it is in the way for straightening out the buffer cache. The right way is to pass the VM page array down through the struct bio to the disk device driver and DMA directly in to/out off the physical memory. Once the VM/buf thing is sorted out it is next on the list. Retire most of vnode method. ffs_getpages(). It is not clear if what is left shouldn't be in the default implementation which we now fall back to. Retire specfs_getpages() as well, as it has no users now.
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_vnops.c117
1 files changed, 5 insertions, 112 deletions
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index bddd2e4..4f44688 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -746,20 +746,9 @@ static int
ffs_getpages(ap)
struct vop_getpages_args *ap;
{
- off_t foff, physoffset;
- int i, size, bsize;
- struct vnode *dp, *vp;
- vm_object_t obj;
- vm_pindex_t pindex;
+ int i;
vm_page_t mreq;
- int bbackwards, bforwards;
- int pbackwards, pforwards;
- int firstpage;
- ufs2_daddr_t reqblkno, reqlblkno;
- int poff;
int pcount;
- int rtval;
- int pagesperblock;
GIANT_REQUIRED;
@@ -787,109 +776,13 @@ ffs_getpages(ap)
return VM_PAGER_OK;
}
VM_OBJECT_UNLOCK(mreq->object);
- vp = ap->a_vp;
- obj = vp->v_object;
- bsize = vp->v_mount->mnt_stat.f_iosize;
- pindex = mreq->pindex;
- foff = IDX_TO_OFF(pindex) /* + ap->a_offset should be zero */;
-
- if (bsize < PAGE_SIZE)
- return vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
- ap->a_count,
- ap->a_reqpage);
-
- /*
- * foff is the file offset of the required page
- * reqlblkno is the logical block that contains the page
- * poff is the index of the page into the logical block
- */
- reqlblkno = foff / bsize;
- poff = (foff % bsize) / PAGE_SIZE;
-
- dp = VTOI(vp)->i_devvp;
- if (ufs_bmaparray(vp, reqlblkno, &reqblkno, 0, &bforwards, &bbackwards)
- || (reqblkno == -1)) {
- VM_OBJECT_LOCK(obj);
- vm_page_lock_queues();
- for(i = 0; i < pcount; i++) {
- if (i != ap->a_reqpage)
- vm_page_free(ap->a_m[i]);
- }
- vm_page_unlock_queues();
- if (reqblkno == -1) {
- if ((mreq->flags & PG_ZERO) == 0)
- pmap_zero_page(mreq);
- vm_page_undirty(mreq);
- mreq->valid = VM_PAGE_BITS_ALL;
- VM_OBJECT_UNLOCK(obj);
- return VM_PAGER_OK;
- } else {
- VM_OBJECT_UNLOCK(obj);
- return VM_PAGER_ERROR;
- }
- }
-
- physoffset = (off_t)reqblkno * DEV_BSIZE + poff * PAGE_SIZE;
- pagesperblock = bsize / PAGE_SIZE;
- /*
- * find the first page that is contiguous...
- * note that pbackwards is the number of pages that are contiguous
- * backwards.
- */
- firstpage = 0;
- if (ap->a_count) {
- pbackwards = poff + bbackwards * pagesperblock;
- if (ap->a_reqpage > pbackwards) {
- firstpage = ap->a_reqpage - pbackwards;
- VM_OBJECT_LOCK(obj);
- vm_page_lock_queues();
- for(i=0;i<firstpage;i++)
- vm_page_free(ap->a_m[i]);
- vm_page_unlock_queues();
- VM_OBJECT_UNLOCK(obj);
- }
- /*
- * pforwards is the number of pages that are contiguous
- * after the current page.
- */
- pforwards = (pagesperblock - (poff + 1)) +
- bforwards * pagesperblock;
- if (pforwards < (pcount - (ap->a_reqpage + 1))) {
- VM_OBJECT_LOCK(obj);
- vm_page_lock_queues();
- for( i = ap->a_reqpage + pforwards + 1; i < pcount; i++)
- vm_page_free(ap->a_m[i]);
- vm_page_unlock_queues();
- VM_OBJECT_UNLOCK(obj);
- pcount = ap->a_reqpage + pforwards + 1;
- }
-
- /*
- * number of pages for I/O corrected for the non-contig pages at
- * the beginning of the array.
- */
- pcount -= firstpage;
- }
-
- /*
- * calculate the size of the transfer
- */
-
- size = pcount * PAGE_SIZE;
-
- if ((IDX_TO_OFF(ap->a_m[firstpage]->pindex) + size) >
- obj->un_pager.vnp.vnp_size)
- size = obj->un_pager.vnp.vnp_size -
- IDX_TO_OFF(ap->a_m[firstpage]->pindex);
-
- physoffset -= foff;
- rtval = VOP_GETPAGES(dp, &ap->a_m[firstpage], size,
- (ap->a_reqpage - firstpage), physoffset);
-
- return (rtval);
+ return vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
+ ap->a_count,
+ ap->a_reqpage);
}
+
/*
* Extended attribute area reading.
*/
OpenPOWER on IntegriCloud