diff options
| author | Poul-Henning Kamp <phk@FreeBSD.org> | 2004-09-19 08:14:55 +0000 |
|---|---|---|
| committer | Poul-Henning Kamp <phk@FreeBSD.org> | 2004-09-19 08:14:55 +0000 |
| commit | d705e025d081243bb1f1e79b433e70a1f08f579f (patch) | |
| tree | 5b390f8ea232bc2f34d1fc7214e483cdd31abbd8 /sys/fs | |
| parent | 710df706de92baea4c5fb099f177a7a92f473861 (diff) | |
Notes
Diffstat (limited to 'sys/fs')
| -rw-r--r-- | sys/fs/specfs/spec_vnops.c | 181 |
1 files changed, 0 insertions, 181 deletions
diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c index 79a924fbf0f97..51334960757d1 100644 --- a/sys/fs/specfs/spec_vnops.c +++ b/sys/fs/specfs/spec_vnops.c @@ -55,7 +55,6 @@ static int spec_advlock(struct vop_advlock_args *); static int spec_close(struct vop_close_args *); static int spec_fsync(struct vop_fsync_args *); -static int spec_getpages(struct vop_getpages_args *); static int spec_ioctl(struct vop_ioctl_args *); static int spec_kqfilter(struct vop_kqfilter_args *); static int spec_open(struct vop_open_args *); @@ -74,7 +73,6 @@ static struct vnodeopv_entry_desc spec_vnodeop_entries[] = { { &vop_close_desc, (vop_t *) spec_close }, { &vop_create_desc, (vop_t *) vop_panic }, { &vop_fsync_desc, (vop_t *) spec_fsync }, - { &vop_getpages_desc, (vop_t *) spec_getpages }, { &vop_getwritemount_desc, (vop_t *) vop_stdgetwritemount }, { &vop_ioctl_desc, (vop_t *) spec_ioctl }, { &vop_kqfilter_desc, (vop_t *) spec_kqfilter }, @@ -640,182 +638,3 @@ spec_advlock(ap) return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL); } - -static int -spec_getpages(ap) - struct vop_getpages_args *ap; -{ - vm_offset_t kva; - int error; - int i, pcount, size, s; - daddr_t blkno; - struct buf *bp; - vm_page_t m; - vm_ooffset_t offset; - int toff, nextoff, nread; - struct vnode *vp = ap->a_vp; - int blksiz; - int gotreqpage; - - GIANT_REQUIRED; - - error = 0; - pcount = round_page(ap->a_count) / PAGE_SIZE; - - /* - * Calculate the offset of the transfer and do a sanity check. - * FreeBSD currently only supports an 8 TB range due to b_blkno - * being in DEV_BSIZE ( usually 512 ) byte chunks on call to - * VOP_STRATEGY. XXX - */ - offset = IDX_TO_OFF(ap->a_m[0]->pindex) + ap->a_offset; - blkno = btodb(offset); - - /* - * Round up physical size for real devices. We cannot round using - * v_mount's block size data because v_mount has nothing to do with - * the device. i.e. it's usually '/dev'. We need the physical block - * size for the device itself. - * - * We can't use v_rdev->si_mountpoint because it only exists when the - * block device is mounted. However, we can use v_rdev. - */ - - if (vn_isdisk(vp, NULL)) - blksiz = vp->v_rdev->si_bsize_phys; - else - blksiz = DEV_BSIZE; - - size = (ap->a_count + blksiz - 1) & ~(blksiz - 1); - - bp = getpbuf(NULL); - kva = (vm_offset_t)bp->b_data; - - /* - * Map the pages to be read into the kva. - */ - pmap_qenter(kva, ap->a_m, pcount); - - /* Build a minimal buffer header. */ - bp->b_iocmd = BIO_READ; - bp->b_iodone = bdone; - - KASSERT(bp->b_rcred == NOCRED, ("leaking read ucred")); - KASSERT(bp->b_wcred == NOCRED, ("leaking write ucred")); - bp->b_rcred = crhold(curthread->td_ucred); - bp->b_wcred = crhold(curthread->td_ucred); - bp->b_iooffset = offset; - bp->b_blkno = blkno; - bp->b_lblkno = blkno; - pbgetvp(ap->a_vp, bp); - bp->b_bcount = size; - bp->b_bufsize = size; - bp->b_resid = 0; - bp->b_runningbufspace = bp->b_bufsize; - runningbufspace += bp->b_runningbufspace; - - cnt.v_vnodein++; - cnt.v_vnodepgsin += pcount; - - /* Do the input. */ - spec_xstrategy(bp->b_vp, bp); - - s = splbio(); - bwait(bp, PVM, "spread"); - splx(s); - - if ((bp->b_ioflags & BIO_ERROR) != 0) { - if (bp->b_error) - error = bp->b_error; - else - error = EIO; - } - - nread = size - bp->b_resid; - - if (nread < ap->a_count) { - bzero((caddr_t)kva + nread, - ap->a_count - nread); - } - pmap_qremove(kva, pcount); - - gotreqpage = 0; - /* - * While the page is busy, its object field is immutable. - */ - VM_OBJECT_LOCK(ap->a_m[ap->a_reqpage]->object); - vm_page_lock_queues(); - for (i = 0, toff = 0; i < pcount; i++, toff = nextoff) { - nextoff = toff + PAGE_SIZE; - m = ap->a_m[i]; - - if (nextoff <= nread) { - m->valid = VM_PAGE_BITS_ALL; - vm_page_undirty(m); - } else if (toff < nread) { - /* - * Since this is a VM request, we have to supply the - * unaligned offset to allow vm_page_set_validclean() - * to zero sub-DEV_BSIZE'd portions of the page. - */ - vm_page_set_validclean(m, 0, nread - toff); - } else { - m->valid = 0; - vm_page_undirty(m); - } - - if (i != ap->a_reqpage) { - /* - * Just in case someone was asking for this page we - * now tell them that it is ok to use. - */ - if (!error || (m->valid == VM_PAGE_BITS_ALL)) { - if (m->valid) { - if (m->flags & PG_WANTED) { - vm_page_activate(m); - } else { - vm_page_deactivate(m); - } - vm_page_wakeup(m); - } else { - vm_page_free(m); - } - } else { - vm_page_free(m); - } - } else if (m->valid) { - gotreqpage = 1; - /* - * Since this is a VM request, we need to make the - * entire page presentable by zeroing invalid sections. - */ - if (m->valid != VM_PAGE_BITS_ALL) - vm_page_zero_invalid(m, FALSE); - } - } - vm_page_unlock_queues(); - if (!gotreqpage) { - m = ap->a_m[ap->a_reqpage]; - printf( - "spec_getpages:(%s) I/O read failure: (error=%d) bp %p vp %p\n", - devtoname(bp->b_dev), error, bp, bp->b_vp); - printf( - " size: %d, resid: %ld, a_count: %d, valid: 0x%lx\n", - size, bp->b_resid, ap->a_count, (u_long)m->valid); - printf( - " nread: %d, reqpage: %d, pindex: %lu, pcount: %d\n", - nread, ap->a_reqpage, (u_long)m->pindex, pcount); - VM_OBJECT_UNLOCK(m->object); - /* - * Free the buffer header back to the swap buffer pool. - */ - relpbuf(bp, NULL); - return VM_PAGER_ERROR; - } - VM_OBJECT_UNLOCK(ap->a_m[ap->a_reqpage]->object); - /* - * Free the buffer header back to the swap buffer pool. - */ - relpbuf(bp, NULL); - return VM_PAGER_OK; -} |
