* This is now called from local media FS's to operate against their * own vnodes if they fail to implement VOP_GETPAGES. */
| 790 | * own vnodes if they fail to implement VOP_GETPAGES. |
| 791 | */ |
| 792 | int |
| 793 | vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *m, int count, |
| 794 | int *a_rbehind, int *a_rahead, vop_getpages_iodone_t iodone, void *arg) |
| 795 | { |
| 796 | vm_object_t object; |
| 797 | struct bufobj *bo; |
| 798 | struct buf *bp; |
| 799 | off_t foff; |
| 800 | #ifdef INVARIANTS |
| 801 | off_t blkno0; |
| 802 | #endif |
| 803 | int bsize, pagesperblock; |
| 804 | int error, before, after, rbehind, rahead, poff, i; |
| 805 | int bytecount, secmask; |
| 806 | |
| 807 | KASSERT(vp->v_type != VCHR && vp->v_type != VBLK, |
| 808 | ("%s does not support devices", __func__)); |
| 809 | |
| 810 | if (VN_IS_DOOMED(vp)) |
| 811 | return (VM_PAGER_BAD); |
| 812 | |
| 813 | object = vp->v_object; |
| 814 | foff = IDX_TO_OFF(m[0]->pindex); |
| 815 | bsize = vp->v_mount->mnt_stat.f_iosize; |
| 816 | pagesperblock = bsize / PAGE_SIZE; |
| 817 | |
| 818 | KASSERT(foff < object->un_pager.vnp.vnp_size, |
| 819 | ("%s: page %p offset beyond vp %p size", __func__, m[0], vp)); |
| 820 | KASSERT(count <= atop(maxphys), |
| 821 | ("%s: requested %d pages", __func__, count)); |
| 822 | |
| 823 | /* |
| 824 | * The last page has valid blocks. Invalid part can only |
| 825 | * exist at the end of file, and the page is made fully valid |
| 826 | * by zeroing in vm_pager_get_pages(). |
| 827 | */ |
| 828 | if (!vm_page_none_valid(m[count - 1]) && --count == 0) { |
| 829 | if (iodone != NULL) |
| 830 | iodone(arg, m, 1, 0); |
| 831 | return (VM_PAGER_OK); |
| 832 | } |
| 833 | |
| 834 | bp = uma_zalloc(vnode_pbuf_zone, M_WAITOK); |
| 835 | MPASS((bp->b_flags & B_MAXPHYS) != 0); |
| 836 | |
| 837 | /* |
| 838 | * Get the underlying device blocks for the file with VOP_BMAP(). |
| 839 | * If the file system doesn't support VOP_BMAP, use old way of |
| 840 | * getting pages via VOP_READ. |
| 841 | */ |
| 842 | error = VOP_BMAP(vp, foff / bsize, &bo, &bp->b_blkno, &after, &before); |
| 843 | if (error == EOPNOTSUPP) { |
| 844 | uma_zfree(vnode_pbuf_zone, bp); |
| 845 | VM_OBJECT_WLOCK(object); |
| 846 | for (i = 0; i < count; i++) { |
| 847 | VM_CNT_INC(v_vnodein); |
| 848 | VM_CNT_INC(v_vnodepgsin); |
| 849 | error = vnode_pager_input_old(object, m[i]); |
no test coverage detected