📄 vnode.c
字号:
}/****************************************************************************//* * get page routine * This is called only if the pages are NOT in the cache! * XXX: ap->a_offset is always ignored */static intwrapfs_getpages(ap) struct vop_getpages_args /* { struct vnode *a_vp; vm_page_t *a_m; int a_count; int a_reqpage; vm_ooffset_t a_offset; } */ *ap;{ int error = VM_PAGER_ERROR; struct vnode *vp = ap->a_vp; struct vnode *lowervp = WRAPFS_VP_TO_LOWERVP(vp); int reqpage = ap->a_reqpage; int bytecount = ap->a_count; vm_page_t thispp; int i, resid; int pagecount = round_page(bytecount) / PAGE_SIZE; vm_offset_t thiskva; caddr_t thisca; uio_t temp_uio; iovec_t *free_iovecp, *free_iovarr; cred_t *cr = curproc->p_ucred; fist_dprint(2, "WRAPFS_GETPAGES: vp=0x%x, lowervp=0x%x, m=0x%x, pages=%d, bytes=%d, reqpage=%d, offset=%d\n", /* XXX: change level to 4 */ (int) vp, (int) lowervp, (int) ap->a_m, pagecount, bytecount, reqpage, (int) ap->a_offset ); wrapfs_verify_lower_object(vp, __FUNCTION__); /* prepare for a VOP_READ on the lowervp data straight into this vp's pages */ temp_uio.uio_resid = bytecount; temp_uio.uio_offset = IDX_TO_OFF(ap->a_m[0]->pindex); temp_uio.uio_segflg = UIO_SYSSPACE; temp_uio.uio_rw = UIO_READ; temp_uio.uio_procp = curproc; temp_uio.uio_iovcnt = pagecount; temp_uio.uio_iov = free_iovarr = (iovec_t *) kmem_zalloc(pagecount * sizeof(iovec_t)); free_iovecp = (iovec_t *) kmem_zalloc(pagecount * sizeof(iovec_t)); if (!temp_uio.uio_iov || !free_iovecp) { error = VM_PAGER_AGAIN; printf("GetPages: nore more memory for temp uio\n"); goto out; } /* setup pointers to each page to read */ for (i = 0; i < pagecount; i++) { temp_uio.uio_iov[i].iov_base = free_iovecp[i].iov_base = kmem_zalloc(PAGE_SIZE); if (!free_iovecp[i].iov_base) { error = VM_PAGER_AGAIN; printf("GetPages: nore more memory for temp iovecs\n"); goto out; } temp_uio.uio_iov[i].iov_len = free_iovecp[i].iov_len = PAGE_SIZE; } /* do the actual VOP_READ */ error = VOP_READ(lowervp, &temp_uio, (IO_VMIO | IO_SYNC), curproc->p_ucred); if (error) { printf("GETPAGES: read on behalf of vmio failed with error %d\n", error); error = VM_PAGER_ERROR; goto out; } /* if residual is non-zero, do nothing since rest of pages were zalloc'ed */ resid = temp_uio.uio_resid; if (resid > PAGE_SIZE) panic("GETPAGES: temp_iovec.uio_resid is %d > PAGE_SIZE\n", resid); /* copy and decode all the bytes */ for (i = 0; i < pagecount; i++) { thispp = ap->a_m[i]; thiskva = vm_pager_map_page(thispp); thisca = (caddr_t) thiskva; bcopy(free_iovecp[i].iov_base, thisca, PAGE_SIZE); wrapfs_decode_block(thisca, thisca, PAGE_SIZE, vp, vp->v_mount); vm_pager_unmap_page(thiskva); } /* set status of pages to valid and non-busy as needed */ for (i = 0; i < pagecount; i++) { thispp = ap->a_m[i]; thispp->valid = VM_PAGE_BITS_ALL; if (i == reqpage) thispp->flags |= PG_BUSY; /* requested page must be busy */ else thispp->flags &= ~PG_BUSY; /* XXX: others need not? */ fist_print_page("getpages: thispp0", thispp); } error = VM_PAGER_OK;out: if (free_iovecp) { for (i = 0; i < pagecount; i++) if (free_iovecp[i].iov_base) kmem_free(free_iovecp[i].iov_base); kmem_free(free_iovecp); } if (free_iovarr) kmem_free(free_iovarr); print_location(); return (error);}/* * put page routine * XXX: ap->a_offset is always ignored */static intwrapfs_putpages(ap) struct vop_putpages_args /* { struct vnode *a_vp; vm_page_t *a_m; int a_count; int a_sync; int *a_rtvals; vm_ooffset_t a_offset; } */ *ap;{ int error; struct vnode *vp = ap->a_vp; struct vnode *lowervp = WRAPFS_VP_TO_LOWERVP(vp); int bytecount = ap->a_count; int pagecount = round_page(bytecount) / PAGE_SIZE; vm_page_t thispp; int i, resid; vm_offset_t thiskva; caddr_t thisca; uio_t temp_uio; iovec_t *free_iovecp, *free_iovarr; cred_t *cr = curproc->p_ucred; fist_dprint(2, "WRAPFS_PUTPAGES: vp=0x%x, lowervp=0x%x, sync=0x%x\n", (int) vp, (int) lowervp, ap->a_sync); /* prepare for a VOP_WRITE on the lowervp data straight into this vp's pages */ temp_uio.uio_resid = bytecount; temp_uio.uio_offset = IDX_TO_OFF(ap->a_m[0]->pindex); temp_uio.uio_segflg = UIO_SYSSPACE; temp_uio.uio_rw = UIO_WRITE; temp_uio.uio_procp = curproc; temp_uio.uio_iovcnt = pagecount; temp_uio.uio_iov = free_iovarr = (iovec_t *) kmem_zalloc(pagecount * sizeof(iovec_t)); free_iovecp = (iovec_t *) kmem_zalloc(pagecount * sizeof(iovec_t)); if (!temp_uio.uio_iov || !free_iovecp) { error = VM_PAGER_AGAIN; printf("PutPages: nore more memory for temp uio\n"); goto out; } /* setup pointers to each page to write */ for (i = 0; i < pagecount; i++) { temp_uio.uio_iov[i].iov_base = free_iovecp[i].iov_base = kmem_zalloc(PAGE_SIZE); if (!free_iovecp[i].iov_base) { error = VM_PAGER_AGAIN; printf("PutPages: nore more memory for temp iovecs\n"); goto out; } temp_uio.uio_iov[i].iov_len = free_iovecp[i].iov_len = PAGE_SIZE; } /* copy and decode all the bytes */ for (i = 0; i < pagecount; i++) { thispp = ap->a_m[i]; thiskva = vm_pager_map_page(thispp); thisca = (caddr_t) thiskva; bcopy(thisca, free_iovecp[i].iov_base, PAGE_SIZE); wrapfs_encode_block(free_iovecp[i].iov_base, free_iovecp[i].iov_base, PAGE_SIZE, vp, vp->v_mount); vm_pager_unmap_page(thiskva); } /* do the actual VOP_WRITE */ error = VOP_WRITE(lowervp, &temp_uio, (IO_VMIO | IO_SYNC), curproc->p_ucred); if (error) { printf("PUTPAGES: write on behalf of vmio failed with error %d\n", error); error = VM_PAGER_ERROR; goto out; } /* if residual is non-zero, do nothing since rest of pages were zalloc'ed */ resid = temp_uio.uio_resid; if (resid > PAGE_SIZE) panic("PUTPAGES: temp_iovec.uio_resid is %d > PAGE_SIZE\n", resid); /* set status of pages to valid and non-busy as needed */ for (i = 0; i < pagecount; i++) { thispp = ap->a_m[i]; thispp->valid = VM_PAGE_BITS_ALL; thispp->flags &= ~PG_BUSY; fist_print_page("putpages: thispp0", thispp); } error = VM_PAGER_OK;out: if (free_iovecp) { for (i = 0; i < pagecount; i++) if (free_iovecp[i].iov_base) kmem_free(free_iovecp[i].iov_base); kmem_free(free_iovecp); } if (free_iovarr) kmem_free(free_iovarr); print_location(); return (error);}#ifdef HAVE_BMAPstatic intwrapfs_bmap(ap) struct vop_bmap_args /* { struct vnode *a_vp; daddr_t a_bn; struct vnode **a_vpp; daddr_t *a_bnp; int *a_runp; int *a_runb; } */ *ap;{ int error = 0; struct vnode *vp = ap->a_vp; struct vnode *lowervp = WRAPFS_VP_TO_LOWERVP(vp); fist_dprint(4, "WRAPFS_BMAP:0x%x:0x%x\n", (int) ap->a_vpp, (int) lowervp); printf("WRAPFS_BMAP:0x%x:0x%x\n", (int) ap->a_vpp, (int) lowervp); wrapfs_verify_lower_object(vp, __FUNCTION__);#if 0 ap->a_vp = lowervp; error = VCALL(lowervp, VOFFSET(vop_bmap), ap); return (error);#endif#if 1 error = wrapfs_bypass((struct vop_generic_args *) ap); return (error);#endif#if 0 /* this code also doesn't panic */ if (ap->a_vpp != NULL) *ap->a_vpp = ap->a_vp; if (ap->a_bnp != NULL) *ap->a_bnp = ap->a_bn; if (ap->a_runp != NULL) *ap->a_runp = 0; if (ap->a_runb != NULL) *ap->a_runb = 0; return (error);#endif#if 0 error = EINVAL; return (error);#endif}#endif /* HAVE_BMAP */static intwrapfs_mmap(ap) struct vop_mmap_args /* { struct vnode *a_vp; int a_fflags; struct ucred *a_cred; struct proc *a_p; } */ *ap;{ int error; struct vnode *vp = ap->a_vp; struct vnode *lowervp = WRAPFS_VP_TO_LOWERVP(vp); fist_dprint(4, "WRAPFS_MMAP: vp=0x%x\n", (int) vp); printf("WRAPFS_MMAP: vp=0x%x\n", (int) vp); wrapfs_verify_lower_object(vp, __FUNCTION__); error = VOP_MMAP(lowervp, ap->a_fflags, ap->a_cred, ap->a_p); return (error);}#ifdef FIST_FILTER_NAMEstatic intwrapfs_mkdir(ap) struct vop_mkdir_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; struct vattr *a_vap; } */ *ap;{ int error; vnode_t *thisdvp = ap->a_dvp; vnode_t *lowerdvp = WRAPFS_VP_TO_LOWERVP(thisdvp); CNP_VARS; fist_dprint(2, "WRAPFS_MKDIR: lowerdvp=0x%x\n", (int) lowerdvp); CNP_BEFORE(thisdvp); error = wrapfs_bypass((struct vop_generic_args *) ap); CNP_AFTER(thisdvp); print_location(); return (error);}static intwrapfs_rmdir(ap) struct vop_rmdir_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; } */ *ap;{ int error; vnode_t *thisdvp = ap->a_dvp; vnode_t *thisvp = ap->a_vp; vnode_t *lowerdvp = WRAPFS_VP_TO_LOWERVP(thisdvp); vnode_t *lowervp = WRAPFS_VP_TO_LOWERVP(thisvp); CNP_VARS; fist_dprint(2, "WRAPFS_RMDIR: lowerdvp=0x%x lowervp=0x%x\n", (int) lowerdvp, (int) lowervp); CNP_BEFORE(thisvp); error = wrapfs_bypass((struct vop_generic_args *) ap); CNP_AFTER(thisvp); print_location(); return (error);}static intwrapfs_create(ap) struct vop_create_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; struct vattr *a_vap; } */ *ap;{ int error; vnode_t *thisdvp = ap->a_dvp; vnode_t *lowerdvp = WRAPFS_VP_TO_LOWERVP(thisdvp); CNP_VARS; fist_dprint(2, "WRAPFS_CREATE: lowerdvp=0x%x\n", (int) lowerdvp); CNP_BEFORE(thisdvp); error = wrapfs_bypass((struct vop_generic_args *) ap); CNP_AFTER(thisdvp); print_location(); return (error);}static intwrapfs_remove(ap) struct vop_remove_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; } */ *ap;{ int error; vnode_t *thisdvp = ap->a_dvp; vnode_t *lowerdvp = WRAPFS_VP_TO_LOWERVP(ap->a_dvp); vnode_t *lowervp = WRAPFS_VP_TO_LOWERVP(ap->a_vp); CNP_VARS; fist_dprint(2, "WRAPFS_REMOVE: lowerdvp=0x%x lowervp=0x%x\n", (int) lowerdvp, (int) lowervp); CNP_BEFORE(thisdvp); error = wrapfs_bypass((struct vop_generic_args *) ap); CNP_AFTER(thisdvp); return (error);}static intwrapfs_rename(ap) struct vop_rename_args /* { struct vnode *a_fdvp; struct vnode *a_fvp; struct componentname *a_fcnp; struct vnode *a_tdvp; struct vnode *a_tvp; struct componentname *a_tcnp; } */ *ap;{ int error; vnode_t *thisfdvp = ap->a_fdvp; vnode_t *thisfvp = ap->a_fvp; vnode_t *thistdvp = ap->a_tdvp; vnode_t *thistvp = ap->a_tvp; /* this one comes in as NULL! */ vnode_t *lowerfdvp = WRAPFS_VP_TO_LOWERVP(thisfdvp); vnode_t *lowerfvp = WRAPFS_VP_TO_LOWERVP(thisfvp); vnode_t *lowertdvp = WRAPFS_VP_TO_LOWERVP(thistdvp); vnode_t *lowertvp = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -