diff options
author | phk <phk@FreeBSD.org> | 2004-09-19 08:14:55 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2004-09-19 08:14:55 +0000 |
commit | 73cf913d5f9c8b5932556b4f8630059a82fe0b22 (patch) | |
tree | 5b390f8ea232bc2f34d1fc7214e483cdd31abbd8 /sys/ufs | |
parent | 869702f330fe71fea7521b27b2b88095a0a70861 (diff) | |
download | FreeBSD-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.c | 117 |
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. */ |