void fiov_refresh(struct fuse_iov *fiov) { debug_printf("fiov=%p\n", fiov); bzero(fiov->base, fiov->len); fiov_adjust(fiov, 0); }
static __inline__ int fticket_aw_pull_uio(struct fuse_ticket *ftick, struct uio *uio) { int err = 0; size_t len = uio_resid(uio); debug_printf("ftick=%p, uio=%p\n", ftick, uio); if (len) { switch (ftick->tk_aw_type) { case FT_A_FIOV: fiov_adjust(fticket_resp(ftick), len); err = uiomove(fticket_resp(ftick)->base, len, uio); if (err) { debug_printf("FUSE: FT_A_FIOV: error is %d" " (%p, %zd, %p)\n", err, fticket_resp(ftick)->base, len, uio); } break; case FT_A_BUF: ftick->tk_aw_bufsize = len; err = uiomove(ftick->tk_aw_bufdata, len, uio); if (err) { debug_printf("FUSE: FT_A_BUF: error is %d" " (%p, %zd, %p)\n", err, ftick->tk_aw_bufdata, len, uio); } break; default: panic("FUSE: unknown answer type for ticket %p", ftick); } } return err; }
int fuse_internal_readdir_processdata(struct uio *uio, size_t reqsize, void *buf, size_t bufsize, void *param) { int err = 0; int cou = 0; int bytesavail; size_t freclen; struct dirent *de; struct fuse_dirent *fudge; struct fuse_iov *cookediov = param; if (bufsize < FUSE_NAME_OFFSET) { return -1; } for (;;) { if (bufsize < FUSE_NAME_OFFSET) { err = -1; break; } fudge = (struct fuse_dirent *)buf; freclen = FUSE_DIRENT_SIZE(fudge); cou++; if (bufsize < freclen) { err = ((cou == 1) ? -1 : 0); break; } #ifdef ZERO_PAD_INCOMPLETE_BUFS if (isbzero(buf, FUSE_NAME_OFFSET)) { err = -1; break; } #endif if (!fudge->namelen || fudge->namelen > MAXNAMLEN) { err = EINVAL; break; } bytesavail = GENERIC_DIRSIZ((struct pseudo_dirent *) &fudge->namelen); if (bytesavail > uio_resid(uio)) { err = -1; break; } fiov_refresh(cookediov); fiov_adjust(cookediov, bytesavail); de = (struct dirent *)cookediov->base; de->d_fileno = fudge->ino; /* XXX: truncation */ de->d_reclen = bytesavail; de->d_type = fudge->type; de->d_namlen = fudge->namelen; memcpy((char *)cookediov->base + sizeof(struct dirent) - MAXNAMLEN - 1, (char *)buf + FUSE_NAME_OFFSET, fudge->namelen); ((char *)cookediov->base)[bytesavail] = '\0'; err = uiomove(cookediov->base, cookediov->len, uio); if (err) { break; } buf = (char *)buf + freclen; bufsize -= freclen; uio_setoffset(uio, fudge->off); } return err; }
__private_extern__ int fuse_internal_readdir_processdata(vnode_t vp, uio_t uio, __unused size_t reqsize, void *buf, size_t bufsize, struct fuse_iov *cookediov, int *numdirent) { int err = 0; int cou = 0; int n = 0; size_t bytesavail; size_t freclen; struct dirent *de; struct fuse_dirent *fudge; if (bufsize < FUSE_NAME_OFFSET) { return -1; } for (;;) { if (bufsize < FUSE_NAME_OFFSET) { err = -1; break; } fudge = (struct fuse_dirent *)buf; freclen = FUSE_DIRENT_SIZE(fudge); cou++; if (bufsize < freclen) { err = ((cou == 1) ? -1 : 0); break; } /* * if (isbzero(buf, FUSE_NAME_OFFSET)) { * // zero-pad incomplete buffer * ... * err = -1; * break; * } */ if (!fudge->namelen) { err = EINVAL; break; } if (fudge->namelen > FUSE_MAXNAMLEN) { err = EIO; break; } #define GENERIC_DIRSIZ(dp) \ ((sizeof(struct dirent) - (FUSE_MAXNAMLEN + 1)) + \ (((dp)->d_namlen + 1 + 3) & ~3)) bytesavail = GENERIC_DIRSIZ((struct pseudo_dirent *)&fudge->namelen); if (bytesavail > (size_t)uio_resid(uio)) { err = -1; break; } fiov_refresh(cookediov); fiov_adjust(cookediov, bytesavail); de = (struct dirent *)cookediov->base; #if __DARWIN_64_BIT_INO_T de->d_fileno = fudge->ino; #else de->d_fileno = (ino_t)fudge->ino; /* XXX: truncation */ #endif /* __DARWIN_64_BIT_INO_T */ de->d_reclen = bytesavail; de->d_type = fudge->type; de->d_namlen = fudge->namelen; /* Filter out any ._* files if the mount is configured as such. */ if (fuse_skip_apple_double_mp(vnode_mount(vp), fudge->name, fudge->namelen)) { de->d_fileno = 0; de->d_type = DT_WHT; } memcpy((char *)cookediov->base + sizeof(struct dirent) - FUSE_MAXNAMLEN - 1, (char *)buf + FUSE_NAME_OFFSET, fudge->namelen); ((char *)cookediov->base)[bytesavail] = '\0'; err = uiomove(cookediov->base, (int)cookediov->len, uio); if (err) { break; } n++; buf = (char *)buf + freclen; bufsize -= freclen; uio_setoffset(uio, fudge->off); } if (!err && numdirent) { *numdirent = n; } return err; }