📄 vnode.c
字号:
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);}#else /* FIST_COHERENCY */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 = 0; 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 *lowerm; vm_page_t mreq = ap->a_m[reqpage]; int i, resid; int pagecount = round_page(bytecount) / PAGE_SIZE; vm_offset_t thiskva, lowerkva; caddr_t thisca, lowerca; vm_object_t obj = vp->v_object; vm_object_t lower_obj; fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__); fist_print_object(__FUNCTION__, obj); if (vp->v_mount == NULL) return VM_PAGER_BAD; if (mreq->valid) { for (i = 0; i < pagecount; i++) { if (i != reqpage) { vnode_pager_freepage(ap->a_m[i]); } else if (ap->a_m[i]->valid != VM_PAGE_BITS_ALL) { vm_page_zero_invalid(mreq,TRUE); } } return VM_PAGER_OK; } error = VOP_GETVOBJECT(lowervp, &lower_obj); if (error) { printk(" unable to get lower vm_object \n"); return error; } vm_object_reference(lower_obj); vm_object_pip_add(lower_obj, obj->paging_in_progress); /* get the pages for the lower file system */ lowerm = kmem_zalloc(pagecount * sizeof(vm_page_t)); for ( i = 0; i< pagecount ; i++) { lowerm[i] = vm_page_grab(lower_obj, ap->a_m[i]->pindex, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (lowerm[i]->valid == 0) { /* call VOP_GETPAGES on the lower page - offset is ignored */ error = VOP_GETPAGES(lowervp, &lowerm[i], 1, 0, ap->a_offset ); if (error != VM_PAGER_OK) { printk(" wrapfs_getpages failed \n"); continue; } } lowerkva = vm_pager_map_page(lowerm[i]); lowerca = (caddr_t) lowerkva; thiskva = vm_pager_map_page(ap->a_m[i]); thisca = (caddr_t) thiskva; wrapfs_decode_block(lowerca, thisca, PAGE_SIZE, vp, vp->v_mount, ap->a_m[i]->pindex); vm_pager_unmap_page(lowerkva); vm_pager_unmap_page(thiskva); ap->a_m[i]->valid = lowerm[i]->valid; if (lowerm[i]->wire_count == 0 && lowerm[i]->hold_count == 0 && lowerm[i]->busy == 0 && lowerm[i]->flags & PG_BUSY) { vm_page_free(lowerm[i]); } vm_page_wakeup(lowerm[i]); if ( i == reqpage) { vm_page_busy(ap->a_m[i]); } else { if (ap->a_m[i]->flags & PG_BUSY) vnode_pager_freepage(ap->a_m[i]); } fist_print_page("wrapfs_getpages: thispp0", ap->a_m[i]); } vm_object_pip_subtract(lowervp->v_object, lowervp->v_object->paging_in_progress); vm_object_deallocate(lower_obj); error = VM_PAGER_OK;out: kmem_free(lowerm); fist_print_object(__FUNCTION__, vp->v_object); print_location(); return error;}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 = 0; struct vnode *vp = ap->a_vp; struct vnode *lowervp = WRAPFS_VP_TO_LOWERVP(vp); int bytecount = ap->a_count; vm_page_t *lowerm; int i, resid; int pagecount = round_page(bytecount) / PAGE_SIZE; vm_offset_t thiskva, lowerkva; caddr_t thisca, lowerca; vm_object_t obj = vp->v_object; vm_object_t lower_obj; fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__); fist_print_object(__FUNCTION__, obj); if (!lowervp) { printk("no lowervp \n"); return VM_PAGER_BAD; } error = VOP_GETVOBJECT(lowervp, &lower_obj); if (error) { printk(" unable to get lower vm_object \n"); return error; } fist_copy_object_attr(lower_obj, obj); vm_object_pip_add(lowervp->v_object, vp->v_object->paging_in_progress); lowerm = kmem_zalloc(pagecount * sizeof(vm_page_t)); for ( i = 0; i< pagecount ; i++) lowerm[i] = vm_page_grab(lower_obj, ap->a_m[i]->pindex, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); for (i = 0; i < pagecount ; ++i) { /* copy the flags to the lower level vm_page_t */ fist_copy_page_attr(lowerm[i], ap->a_m[i]); lowerkva = vm_pager_map_page(lowerm[i]); lowerca = (caddr_t) lowerkva; thiskva = vm_pager_map_page(ap->a_m[i]); thisca = (caddr_t) thiskva; wrapfs_encode_block( thisca, lowerca, PAGE_SIZE, vp, vp->v_mount, ap->a_m[i]->pindex); vm_pager_unmap_page(lowerkva); vm_pager_unmap_page(thiskva); } error = VOP_PUTPAGES(lowervp, lowerm, bytecount, ap->a_sync, ap->a_rtvals, ap->a_offset); if (error) printf("wrapfs_putpages : error %d ", error); fist_copy_object_attr(vp->v_object, lowervp->v_object); vm_object_pip_subtract(lowervp->v_object, lowervp->v_object->paging_in_progress); /* set status of pages to valid and non-busy as needed */ for (i = 0; i < pagecount; i++) { fist_copy_page_attr(ap->a_m[i], lowerm[i]); if (lowerm[i]->wire_count == 0 && lowerm[i]->hold_count == 0 && lowerm[i]->busy == 0 && lowerm[i]->flags & PG_BUSY ) { vm_page_free(lowerm[i]); } vm_page_wakeup(lowerm[i]); vm_page_flag_clear(ap->a_m[i], PG_BUSY); fist_print_page("wrapfs_putpages: thispp0", ap->a_m[i]); } vp->v_flag &= ~VOBJDIRTY;out: kmem_free(lowerm); fist_print_object(__FUNCTION__, vp->v_object); print_location(); return error;}#endif /* FIST_COHERENCY */#endif /* FIST_FILTER_DATA */#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); printk(" in bmap \n"); 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); if (error) return error;#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;{ return EINVAL;}#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; /* CNP_VARS; */ cn_t *thisfcnp, *lowerfcnp, *thistcnp, *lowertcnp; fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__); /* Check for cross-device rename. */ if ((thisfvp->v_mount != thistdvp->v_mount) || (thistvp && (thisfvp->v_mount != thistvp->v_mount))) { if (thistdvp == thistvp) vrele(thistdvp); else vput(thistdvp); if (thistvp) vput(thistvp); vrele(thisfdvp); vrele(thisfvp); return (EXDEV); } if (thistvp != NULL) /* comes in as null to this function */ lowertvp = WRAPFS_VP_TO_LOWERVP(thistvp); fist_dprint(2, "WRAPFS_RENAME: thisfdvp=0x%x thisfvp=0x%x thistdvp=0x%x thistvp=0x%x\n", (int) thisfdvp, (int) thisfvp, (int) thistdvp, (int) thistvp); fist_dprint(2, "WRAPFS_RENAME: lowerfdvp=0x%x lowerfvp=0x%x lowertdvp=0x%x lowertvp=0x%x\n", (int) lowerfdvp, (int) lowerfvp, (int) lowertdvp, (int) lowertvp); /* CNP_BEFORE(thisvp); */ thisfcnp = ap->a_fcnp; /* save original */ lowerfcnp = wrapfs_new_cnp((thisfdvp), thisfcnp); ap->a_fcnp = lowerfcnp; /* prepare for bypass */ thistcnp = ap->a_tcnp; /* save original */ lowertcnp = wrapfs_new_cnp((thistdvp), thistcnp); ap->a_tcnp = lowertcnp; /* prepare for bypass */ error = wrapfs_bypass((struct vop_generic_args *) ap); /* CNP_AFTER(thisvp); */ if ((thisfcnp->cn_flags & PARAMASK) != (lowerfcnp->cn_flags & PARAMA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -