📄 vnode.c
字号:
/* CNP_VARS; */ cn_t *thisfcnp, *lowerfcnp, *thistcnp, *lowertcnp; 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 & PARAMASK)) panic("%s: FLAGS CHANGED fthis:0x%x flower:0x%x", __FUNCTION__, (int)thisfcnp->cn_flags, (int)lowerfcnp->cn_flags); if ((thistcnp->cn_flags & PARAMASK) != (lowertcnp->cn_flags & PARAMASK)) panic("%s: FLAGS CHANGED tthis:0x%x tlower:0x%x", __FUNCTION__, (int)thistcnp->cn_flags, (int)lowertcnp->cn_flags); wrapfs_update_cnp((thisfdvp), &lowerfcnp, thisfcnp, error); ap->a_fcnp = thisfcnp; /* update for caller */ wrapfs_update_cnp((thistdvp), &lowertcnp, thistcnp, error); ap->a_tcnp = thistcnp; /* update for caller */ print_location(); return (error);}static intwrapfs_link(ap) struct vop_link_args /* { struct vnode *a_tdvp; struct vnode *a_vp; struct componentname *a_cnp; } */ *ap;{ int error; vnode_t *thistdvp = ap->a_tdvp; vnode_t *thisvp = ap->a_vp; vnode_t *lowertdvp = NULL; vnode_t *lowervp = NULL; CNP_VARS; /* MUST make sure we only hard link into our own file system! */ if (thisvp->v_op != wrapfs_vnodeop_p) return EXDEV; lowertdvp = WRAPFS_VP_TO_LOWERVP(thistdvp); lowervp = WRAPFS_VP_TO_LOWERVP(thisvp); fist_dprint(2, "WRAPFS_LINK: lowertdvp=0x%x lowervp=0x%x\n", (int) lowertdvp, (int) lowervp); CNP_BEFORE(thistdvp); error = wrapfs_bypass((struct vop_generic_args *) ap); CNP_AFTER(thistdvp); print_location(); return (error);}static intwrapfs_symlink(ap) struct vop_symlink_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; struct vattr *a_vap; char *a_target; } */ *ap;{ int error; vnode_t *thisdvp = ap->a_dvp; vnode_t *lowerdvp = WRAPFS_VP_TO_LOWERVP(thisdvp); char *lower_target, *this_target; int lower_target_len = 0; CNP_VARS; fist_dprint(2, "WRAPFS_SYMLINK: lowerdvp=0x%x target=\"%s\"\n", (int) lowerdvp, ap->a_target); lower_target_len = wrapfs_encode_filename(ap->a_target, strlen(ap->a_target), &lower_target, DO_DOTS, thisdvp, thisdvp->v_mount); this_target = ap->a_target; /* save pointer */ ap->a_target = lower_target; /* set to encoded name */ CNP_BEFORE(thisdvp); error = wrapfs_bypass((struct vop_generic_args *) ap); CNP_AFTER(thisdvp); ap->a_target = this_target; /* restore pointer */ kmem_free(lower_target); print_location(); return (error);}static intwrapfs_readlink(ap) struct vop_readlink_args /* { struct vnode *a_vp; struct uio *a_uio; struct ucred *a_cred; } */ *ap;{ int error; vnode_t *thisvp = ap->a_vp; vnode_t *lowervp = WRAPFS_VP_TO_LOWERVP(thisvp); uio_t *uiop = ap->a_uio; cred_t *cr = ap->a_cred; iovec_t temp_iovec; uio_t temp_uio; caddr_t temp_addr2free; int bytes_read; int temp_length, target_real_length; char *temp_name; fist_dprint(2, "WRAPFS_READLINK: lowervp=0x%x\n", (int) lowervp); temp_iovec.iov_len = PAGE_SIZE; temp_iovec.iov_base = temp_addr2free = kmem_zalloc(PAGE_SIZE); if (!temp_iovec.iov_base) { printf("no more memory in readlink\n"); error = ENOMEM; goto out; } temp_uio.uio_iov = &temp_iovec; temp_uio.uio_iovcnt = 1; temp_uio.uio_offset = 0; temp_uio.uio_segflg = UIO_SYSSPACE; temp_uio.uio_rw = uiop->uio_rw; temp_uio.uio_procp = uiop->uio_procp; temp_uio.uio_resid = uiop->uio_resid; error = VOP_READLINK(lowervp, &temp_uio, cr); if (error) goto out_free; bytes_read = PAGE_SIZE - temp_iovec.iov_len; temp_length = wrapfs_decode_filename(temp_iovec.iov_base - bytes_read, bytes_read, &temp_name, DO_DOTS, thisvp, thisvp->v_mount); if (temp_length < 0) { /* a checksum error had occured: skip entry */ panic("symlink value encoded with different key than link itself"); } /* must find real string length, which is guaranteed null terminated here */ target_real_length = strlen(temp_name) + 1; fist_dprint(4, "wrapfs_readlink DECODE len=%d, real_len=%d, bytes_read=%d, name=\"%s\"", temp_length, target_real_length, bytes_read, temp_name); fist_uiomove(temp_name, target_real_length, UIO_READ, uiop); /* already OK: uiop->uio_resid and uiop->uio_loffset */out_free: kmem_free(temp_name); kmem_free(temp_addr2free);out: print_location(); return (error);}#if 0static intwrapfs_cachedlookup(ap) struct vop_cachedlookup_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap;{ int error; vnode_t *thisdvp = ap->a_dvp; vnode_t *lowerdvp = WRAPFS_VP_TO_LOWERVP(thisdvp); CNP_VARS; fist_dprint(2, "WRAPFS_CACHEDLOOKUP: lowerdvp=0x%x\n", (int) lowerdvp); panic("WRAPFS_CACHEDLOOKUP: lowerdvp=0x%x\n", (int) lowerdvp); CNP_BEFORE(thisdvp); error = wrapfs_bypass((struct vop_generic_args *) ap); CNP_AFTER(thisdvp); print_location(); return (error);}#endifstatic intwrapfs_whiteout(ap) struct vop_whiteout_args /* { struct vnode *a_dvp; struct componentname *a_cnp; int a_flags; } */ *ap;{ int error; vnode_t *thisdvp = ap->a_dvp; vnode_t *lowerdvp = WRAPFS_VP_TO_LOWERVP(thisdvp); CNP_VARS; fist_dprint(2, "WRAPFS_WHITEOUT: 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_mknod(ap) struct vop_mknod_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_MKNOD: 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_readdir(ap) struct vop_readdir_args /* { struct vnode *a_vp; struct uio *a_uio; struct ucred *a_cred; int *a_eofflag; int *a_ncookies; u_long **a_cookies; } */ *ap;{ int error = EPERM; vnode_t *thisvp = ap->a_vp; vnode_t *lowervp = WRAPFS_VP_TO_LOWERVP(thisvp); cred_t *cr = ap->a_cred; uio_t *uiop = ap->a_uio; uio_t temp_uio; iovec_t temp_iovec; int aux, bytes_read, length, temp_length, tmp, old_reclen; char *temp_name; fist_dprint(2, "WRAPFS_READDIR: lowervp=0x%x ncookies=0x%x\n", (int) lowervp, (int) ap->a_ncookies); if (ap->a_ncookies) panic("WRAPFS_READDIR0: *ncookies=%d (fix the code)\n", *ap->a_ncookies); if (uiop->uio_iovcnt != 1) panic("WRAPFS_READDIR: iovecnt not 1 (=%d)", uiop->uio_iovcnt); temp_iovec.iov_len = uiop->uio_resid; temp_iovec.iov_base = kmem_zalloc(uiop->uio_resid); temp_uio.uio_iov = &temp_iovec; temp_uio.uio_iovcnt = 1; temp_uio.uio_offset = uiop->uio_offset; temp_uio.uio_segflg = UIO_SYSSPACE; temp_uio.uio_rw = uiop->uio_rw; temp_uio.uio_procp = uiop->uio_procp; temp_uio.uio_resid = uiop->uio_resid; /* pass operation to hidden filesystem, and return status */ error = VOP_READDIR(lowervp, &temp_uio, cr, ap->a_eofflag, ap->a_ncookies, ap->a_cookies); bytes_read = uiop->uio_resid - temp_uio.uio_resid; temp_iovec.iov_base -= bytes_read; temp_iovec.iov_len += bytes_read; if (error) goto clean_up;#define crt_dirent ((struct dirent *)(temp_iovec.iov_base + aux)) for (aux = 0; aux < bytes_read; aux += old_reclen) { char *name = temp_name; old_reclen = crt_dirent->d_reclen; fist_dprint(2, "\nRD: old_reclen=%d old_namlen=%d\n", old_reclen, crt_dirent->d_namlen); /* temp_lenth includes the terminating null */ temp_length = wrapfs_decode_filename(crt_dirent->d_name, crt_dirent->d_namlen, &temp_name, /* null terminated */ SKIP_DOTS, thisvp, thisvp->v_mount); if (temp_length >= 0) { FIST_OP_READDIR_CALL; /* * We copy the dirent to userspace only if the csum matched */ strcpy(crt_dirent->d_name, temp_name); /* ok, b/c of terminating null */ length = temp_length - 256 + sizeof(struct dirent); fist_dprint(2, "RD: new length is %d, temp_length %d, struct dirent: %d\n", length, temp_length, sizeof(struct dirent)); if ((tmp = length & 3)) length += 4 - tmp; crt_dirent->d_reclen = length; crt_dirent->d_namlen = temp_length - 1; kmem_free(temp_name); fist_dprint(2, "RD: adding entry \"%s\" of length %d\n", crt_dirent->d_name, crt_dirent->d_reclen); error = fist_uiomove(temp_iovec.iov_base + aux, crt_dirent->d_reclen, UIO_READ, uiop); if (error) goto clean_up; } } uiop->uio_offset = temp_uio.uio_offset;clean_up: kmem_free(temp_iovec.iov_base); print_location(); return (error);}#endif /* FIST_FILTER_NAME *//* * Global vfs data structures */vop_t **wrapfs_vnodeop_p;static struct vnodeopv_entry_desc wrapfs_vnodeop_entries[] ={ {&vop_default_desc, (vop_t *) wrapfs_bypass}, {&vop_access_desc, (vop_t *) wrapfs_access}, {&vop_getattr_desc, (vop_t *) wrapfs_getattr}, {&vop_inactive_desc, (vop_t *) wrapfs_inactive}, {&vop_lock_desc, (vop_t *) wrapfs_lock},#ifdef FIST_FILTER_NAME {&vop_lookup_desc, (vop_t *) vfs_cache_lookup}, /* FIST_FILTER_NAME */#else /* not FIST_FILTER_NAME */ {&vop_lookup_desc, (vop_t *) wrapfs_lookup}, /* FIST_FILTER_NAME */#endif /* not FIST_FILTER_NAME */ {&vop_print_desc, (vop_t *) wrapfs_print}, {&vop_reclaim_desc, (vop_t *) wrapfs_reclaim}, {&vop_setattr_desc, (vop_t *) wrapfs_setattr}, {&vop_unlock_desc, (vop_t *) wrapfs_unlock}, /* EZK added these */ { &vop_read_desc, (vop_t *) wrapfs_read }, { &vop_write_desc, (vop_t *) wrapfs_write }, { &vop_ioctl_desc, (vop_t *) wrapfs_ioctl }, { &vop_getpages_desc, (vop_t *) wrapfs_getpages }, { &vop_putpages_desc, (vop_t *) wrapfs_putpages },#ifdef HAVE_BMAP { &vop_bmap_desc, (vop_t *) wrapfs_bmap },#endif /* HAVE_BMAP */ { &vop_mmap_desc, (vop_t *) wrapfs_mmap },#ifdef FIST_FILTER_NAME { &vop_mkdir_desc, (vop_t *) wrapfs_mkdir }, { &vop_rmdir_desc, (vop_t *) wrapfs_rmdir }, { &vop_create_desc, (vop_t *) wrapfs_create }, { &vop_remove_desc, (vop_t *) wrapfs_remove }, { &vop_rename_desc, (vop_t *) wrapfs_rename }, { &vop_link_desc, (vop_t *) wrapfs_link }, { &vop_symlink_desc, (vop_t *) wrapfs_symlink }, { &vop_readlink_desc, (vop_t *) wrapfs_readlink }, { &vop_readdir_desc, (vop_t *) wrapfs_readdir }, /* also these are new but need to handle DO_NAMES */#if 0 { &vop_cachedlookup_desc, (vop_t *) wrapfs_cachedlookup },#else { &vop_cachedlookup_desc, (vop_t *) wrapfs_lookup },#endif { &vop_whiteout_desc, (vop_t *) wrapfs_whiteout }, { &vop_mknod_desc, (vop_t *) wrapfs_mknod },#endif /* FIST_FILTER_NAME */ {NULL, NULL}};static struct vnodeopv_desc wrapfs_vnodeop_opv_desc = { &wrapfs_vnodeop_p, wrapfs_vnodeop_entries};VNODEOP_SET(wrapfs_vnodeop_opv_desc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -