static int sqfs_hl_op_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { sqfs_err err; sqfs *fs; sqfs_inode *inode; sqfs_dir dir; sqfs_name namebuf; sqfs_dir_entry entry; struct stat st; sqfs_hl_lookup(&fs, NULL, NULL); inode = (sqfs_inode*)(intptr_t)fi->fh; if (sqfs_dir_open(fs, inode, &dir, offset)) return -EINVAL; memset(&st, 0, sizeof(st)); sqfs_dentry_init(&entry, namebuf); while (sqfs_dir_next(fs, &dir, &entry, &err)) { sqfs_off_t doff = sqfs_dentry_next_offset(&entry); st.st_mode = sqfs_dentry_mode(&entry); if (filler(buf, sqfs_dentry_name(&entry), &st, doff)) return 0; } if (err) return -EIO; return 0; }
static void sqfs_ll_op_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) { sqfs_ll_i lli; sqfs_err sqerr; sqfs_name namebuf; sqfs_dir_entry entry; bool found; sqfs_inode inode; if (sqfs_ll_iget(req, &lli, parent)) return; if (!S_ISDIR(lli.inode.base.mode)) { fuse_reply_err(req, ENOTDIR); return; } sqfs_dentry_init(&entry, namebuf); sqerr = sqfs_dir_lookup(&lli.ll->fs, &lli.inode, name, strlen(name), &entry, &found); if (sqerr) { fuse_reply_err(req, EIO); return; } if (!found) { fuse_reply_err(req, ENOENT); return; } if (sqfs_inode_get(&lli.ll->fs, &inode, sqfs_dentry_inode(&entry))) { fuse_reply_err(req, ENOENT); } else { struct fuse_entry_param fentry; memset(&fentry, 0, sizeof(fentry)); if (sqfs_stat(&lli.ll->fs, &inode, &fentry.attr)) { fuse_reply_err(req, EIO); } else { fentry.attr_timeout = fentry.entry_timeout = SQFS_TIMEOUT; fentry.ino = lli.ll->ino_register(lli.ll, &entry); fentry.attr.st_ino = fentry.ino; fuse_reply_entry(req, &fentry); } } }
static void sqfs_ll_op_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) { sqfs_err sqerr; sqfs_dir dir; sqfs_name namebuf; sqfs_dir_entry entry; size_t esize; struct stat st; char *buf = NULL, *bufpos = NULL; sqfs_ll_i *lli = (sqfs_ll_i*)(intptr_t)fi->fh; int err = 0; if (sqfs_dir_open(&lli->ll->fs, &lli->inode, &dir, off)) err = EINVAL; if (!err && !(bufpos = buf = malloc(size))) err = ENOMEM; if (!err) { memset(&st, 0, sizeof(st)); sqfs_dentry_init(&entry, namebuf); while (sqfs_dir_next(&lli->ll->fs, &dir, &entry, &sqerr)) { st.st_ino = lli->ll->ino_fuse_num(lli->ll, &entry); st.st_mode = sqfs_dentry_mode(&entry); esize = sqfs_ll_add_direntry(req, bufpos, size, sqfs_dentry_name(&entry), &st, sqfs_dentry_next_offset(&entry)); if (esize > size) break; bufpos += esize; size -= esize; } if (sqerr) err = EIO; } if (err) fuse_reply_err(req, err); else fuse_reply_buf(req, buf, bufpos - buf); free(buf); }