📄 subr.c
字号:
wrapfs_checkvp(vp, fil, lno) struct vnode *vp; char *fil; int lno;{ struct wrapfs_node *a = VP_TO_WRAPFS(vp); fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);#ifdef notyet /* * Can't do this check because vop_reclaim runs * with a funny vop vector. */ if (vp->v_op != wrapfs_vnodeop_p) { printf ("wrapfs_checkvp: on non-wrapfs-node\n"); while (wrapfs_checkvp_barrier) /*WAIT*/ ; panic("wrapfs_checkvp"); };#endif if (a->wrapfs_lowervp == NULLVP) { /* kiran - should it be WRAPFSVP ? */ /* Should never happen */ int i; u_long *p; printf("vp = %p, ZERO ptr\n", (void *)vp); for (p = (u_long *) a, i = 0; i < 8; i++) printf(" %lx", p[i]); printf("\n"); /* wait for debugger */ while (wrapfs_checkvp_barrier) /*WAIT*/ ; panic("wrapfs_checkvp"); } if (a->wrapfs_lowervp->v_usecount < 1) { int i; u_long *p; printf("vp = %p, unref'ed lowervp\n", (void *)vp); for (p = (u_long *) a, i = 0; i < 8; i++) printf(" %lx", p[i]); printf("\n"); /* wait for debugger */ while (wrapfs_checkvp_barrier) /*WAIT*/ ; panic ("wrapfs with unref'ed lowervp"); };#ifdef notyet printf("wrapfs %x/%d -> %x/%d [%s, %d]\n", WRAPFS_TO_VP(a), WRAPFS_TO_VP(a)->v_usecount, a->wrapfs_lowervp, a->wrapfs_lowervp->v_usecount, fil, lno);#endif print_location(); return a->wrapfs_lowervp;}#endif/****************************************************************************//* ADDED BY EZK *//* allocate memory and zero it */void *kmem_zalloc(unsigned long size){ void *addr; fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__); addr = malloc(size, M_TEMP, M_WAITOK); if (addr) bzero(addr, size); print_location(); return addr;}/* do an I/O move */intfist_uiomove(caddr_t cp, int n, enum uio_rw rwflag, struct uio *uio){ enum uio_rw saved_rwflag; int ret; fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__); if (uio->uio_rw != rwflag) { printf("UIOMOVE mismatching flags: uio->uio_rw=%d, rwflag=%d\n", uio->uio_rw, rwflag); } /* save uio's rwflag */ saved_rwflag = uio->uio_rw; uio->uio_rw = rwflag; ret = uiomove(cp, n, uio); uio->uio_rw = saved_rwflag; print_location(); return ret;}#ifdef FIST_FILTER_NAME/* * create a new (lower) componentname from an existing one * (this level) and encode the inner. */cn_t *wrapfs_new_cnp(const vnode_t *thisvp, const cn_t *thiscnp){ cn_t *lowercnp;#ifdef FIST_FILTER_NAME static char buf[MAXNAMLEN];#else /* not FIST_FILTER_NAME */ int len; char *name = NULL;#endif /* not FIST_FILTER_NAME */ if (!thiscnp) return NULL; lowercnp = kmem_alloc(sizeof(cn_t)); if (!lowercnp) panic("wrapfs_new_cnp: no more memory\n"); /* copy all fields */ bcopy(thiscnp, lowercnp, sizeof(cn_t)); /* fix certain fields temporarily */ lowercnp->cn_pnbuf = NULL; lowercnp->cn_nameptr = NULL; lowercnp->cn_namelen = 0; /* prepare new path name for lookup */#ifdef FIST_FILTER_NAME bcopy(thiscnp->cn_nameptr, buf, thiscnp->cn_namelen); buf[thiscnp->cn_namelen] = '\0'; lowercnp->cn_namelen = wrapfs_encode_filename(buf, thiscnp->cn_namelen, &lowercnp->cn_pnbuf, SKIP_DOTS, thisvp, /* use namei zone alloc */ thisvp->v_mount); /* updated other cnp fields */ lowercnp->cn_namelen--; /* don't count terminating null */ lowercnp->cn_nameptr = lowercnp->cn_pnbuf; /* I always allocate my own lowercnp buffer */#else /* not FIST_FILTER_NAME */ len = thiscnp->cn_namelen; name = zalloc(namei_zone); if (!name) panic("wrapfs_new_cnp: no more memory for name\n"); bcopy(thiscnp->cn_nameptr, name, len+1); name[len] = '\0'; /* just in case (not needed) */ /* updated other cnp fields */ //name[0]++; /* update first char of name ???*/ lowercnp->cn_namelen = len; lowercnp->cn_nameptr = lowercnp->cn_pnbuf = name;#endif /* not FIST_FILTER_NAME */ /* return formed string */ return lowercnp;}/* * Update an old cnp based on a newer one. * Also free previously allocated lowercnp and its fields. */voidwrapfs_update_cnp(const vnode_t *thisvp, cn_t **lowercnpp, cn_t *thiscnp, int error){ /* * free thiscnp if there no error, HASBUF was on, and SAVENAME was off. * XXX: what about SAVESTART (from <sys/namei.h>) */ if (!error && (thiscnp->cn_flags & (HASBUF|SAVENAME|SAVESTART)) == HASBUF) { fist_dprint(2, "UPDATE_CNP: freeing thiscnp->cn_pnbuf \"%s\"\n", thiscnp->cn_pnbuf); zfree(namei_zone, thiscnp->cn_pnbuf); } if (!fist_isdeadcode(*lowercnpp)) { fist_dprint(2, "UPDATE_CNP: lowercnp flags <%s>\n", fist_cn_flags((*lowercnpp)->cn_flags)); } /* always free space used by lowercnp, if not already free'd */ if (fist_isdeadcode(*lowercnpp)) return; if (!fist_isdeadcode((*lowercnpp)->cn_pnbuf)) { if (((*lowercnpp)->cn_flags & (HASBUF|SAVENAME|SAVESTART)) == HASBUF) { fist_dprint(2, "UPDATE_CNP: freeing lowercnp->cn_pnbuf \"%s\"\n", (*lowercnpp)->cn_pnbuf); zfree(namei_zone, (*lowercnpp)->cn_pnbuf); } else { fist_dprint(1, "UPDATE_CNP: not freeing 0x%x \"%s\" <%s>\n", (int) *lowercnpp, (*lowercnpp)->cn_pnbuf, fist_cn_flags((*lowercnpp)->cn_flags)); } } fist_dprint(2, "UPDATE_CNP: freeing lowercnp 0x%x\n", (int) *lowercnpp); kmem_free(*lowercnpp);}#endif /* FIST_FILTER_NAME */#ifdef FIST_FILTER_DATAvoid fist_copy_object_attr(vm_object_t dest, const vm_object_t src){ dest->flags = src->flags;}void fist_copy_page_attr(vm_page_t dest, const vm_page_t src){ dest->flags = src->flags; dest->dirty = src->dirty; dest->valid = src->valid;}/* * used for truncating a file to an offset beyond its current length */intwrapfs_fill_zeros(vnode_t *vp, vattr_t *vap, cred_t * cred, proc_t * p){ int error = 0; vnode_t *hidden_vp; vattr_t hidden_vap; uio_t temp_uio; iovec_t *temp_iovec, *free_iovec; int i; caddr_t current_base; int resid, bytes_read, num_pages, first_page_bytes, real_first_page; long long start_loffset, end_loffset, page_start_loffset; long long page_end_loffset, current_loffset; int hidden_ioflag = IO_NODELOCKED; vm_object_t object; fist_dprint(4, "fist_wrapfs_fill_zeros vp=0x%x new size=0x%x \n", (int) vp, vap->va_size); hidden_vp = WRAPFS_VP_TO_LOWERVP(vp); /* set the size of the vm object */ vnode_pager_setsize(vp, vap->va_size); vnode_pager_setsize(hidden_vp, vap->va_size); /* get the attributes, length is necessary for correct updates */ if ((error = VOP_GETATTR(hidden_vp, &hidden_vap, cred, p))) { fist_dprint(4, "VOP_GETATTR returned error - not good\n"); goto out; } if (hidden_vap.va_size >= vap->va_size) { return 0; } start_loffset = hidden_vap.va_size; end_loffset = vap->va_size; page_start_loffset = start_loffset & ~(PAGE_SIZE - 1); page_end_loffset = end_loffset & ~(PAGE_SIZE - 1); /* * if not multiple of PAGE_SIZE, then the above formula loses one page. * adjust for it */ if (page_end_loffset < end_loffset) page_end_loffset += PAGE_SIZE; num_pages = (page_end_loffset - page_start_loffset) >> PAGE_SHIFT; temp_iovec = kmem_zalloc(num_pages * sizeof(iovec_t)); free_iovec = kmem_zalloc(num_pages * sizeof(iovec_t)); for (i = 0; i < num_pages; i++) { temp_iovec[i].iov_len = free_iovec[i].iov_len = PAGE_SIZE; temp_iovec[i].iov_base = free_iovec[i].iov_base = kmem_zalloc(PAGE_SIZE); } /* read first block XXX check length of file */ temp_uio.uio_iov = temp_iovec; temp_uio.uio_iovcnt = 1; temp_uio.uio_offset = page_start_loffset; temp_uio.uio_segflg = UIO_SYSSPACE; temp_uio.uio_rw = UIO_READ; temp_uio.uio_procp = p; temp_uio.uio_resid = start_loffset - page_start_loffset; fist_print_uios("FILL_ZEROS (before VOP_READ 1)", &temp_uio); error = VOP_READ(hidden_vp, &temp_uio, hidden_ioflag, cred); if (error) { fist_dprint(5, "VOP_READ returned error - not good\n"); goto out_free; } fist_print_uios("FILL_ZEROS (after VOP_READ 1)", &temp_uio); bytes_read = PAGE_SIZE - temp_iovec[0].iov_len; temp_iovec[0].iov_base -= bytes_read; temp_iovec[0].iov_len = PAGE_SIZE; /* decode block read */ wrapfs_decode_block(temp_iovec[0].iov_base, temp_iovec[0].iov_base, bytes_read, vp, vp->v_mount, OFF_TO_IDX(start_loffset)); bzero(temp_iovec[0].iov_base + bytes_read, PAGE_SIZE - bytes_read); /* * Now we are ready to write the bytes within the start/end * cleartext offsets in the buffers we allocated. */ current_loffset = page_start_loffset; for (i = 0; i < num_pages ; i++) { current_base = temp_iovec[i].iov_base; wrapfs_fill_page(vp, temp_iovec[i].iov_base, current_loffset); wrapfs_encode_block(temp_iovec[i].iov_base, temp_iovec[i].iov_base, PAGE_SIZE, vp, vp->v_mount, OFF_TO_IDX(current_loffset)); wrapfs_fill_page(hidden_vp, temp_iovec[i].iov_base, current_loffset); current_loffset += PAGE_SIZE; } resid = end_loffset - page_start_loffset; /* XXX: no need for full initialization here */ temp_uio.uio_iov = temp_iovec; temp_uio.uio_iovcnt = num_pages; temp_uio.uio_offset = page_start_loffset; temp_uio.uio_segflg = UIO_SYSSPACE; temp_uio.uio_rw = UIO_WRITE; temp_uio.uio_procp = p; temp_uio.uio_resid = resid; /* * pass operation to hidden filesystem, and return status */ fist_print_uios("FILL_ZEROS (before write)", &temp_uio); error = VOP_WRITE(hidden_vp, &temp_uio, hidden_ioflag, cred); fist_print_uios("FILL_ZEROS (after write)", &temp_uio);out_free: for (i = 0; i < num_pages; i++) { fist_dprint(6, "PRINT_BASE1 %d: 0x%x (len=%d)\n", i, temp_iovec[i].iov_base, temp_iovec[i].iov_len); kmem_free(free_iovec[i].iov_base); } kmem_free(temp_iovec);out: print_location(); return (error);}#endif /* FIST_FILTER_DATA */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -