static __inline__ void fticket_refresh(struct fuse_ticket *ftick) { debug_printf("ftick=%p\n", ftick); FUSE_ASSERT_MS_DONE(ftick); FUSE_ASSERT_AW_DONE(ftick); fiov_refresh(&ftick->tk_ms_fiov); ftick->tk_ms_bufdata = NULL; ftick->tk_ms_bufsize = 0; ftick->tk_ms_type = FT_M_FIOV; bzero(&ftick->tk_aw_ohead, sizeof(struct fuse_out_header)); fiov_refresh(&ftick->tk_aw_fiov); ftick->tk_aw_errno = 0; ftick->tk_aw_bufdata = NULL; ftick->tk_aw_bufsize = 0; ftick->tk_aw_type = FT_A_FIOV; ftick->tk_flag = 0; }
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; }