【发布时间】:2022-05-11 00:41:41
【问题描述】:
为什么在我的 fuse 文件系统中尝试 ls . 命令时会导致 I/O 错误?
我的文件系统有一个限制,它只允许邮件地址类型作为单独的文件名,并且不允许子目录。
现在我想在使用ls .时显示文件名列表,但它不起作用。
我知道它必须实现一个回调函数。 (对应函数为mycode中的ll_readdir)
但我不知道是什么点导致了错误。
更新:
现在我使用strace 命令来调查是什么系统调用引发了这个错误。
根据strace的结果,这个错误是在getdents64系统调用中引起的。
getdents64(3, 0x5611ed000540, 32768) = -1 EIO (Input/output error)
Code1(mm的实现:
struct mutex_map {
int counter = 2;
std::mutex _mtx;
std::unordered_map<int, std::string> _data;
std::unordered_map<std::string, int> _rev_data;
public:
int set_value(const char* value) {
std::string s = std::string(value);
std::lock_guard<std::mutex> lock(_mtx);
counter++;
_data[counter] = s;
_rev_data[s] = counter;
return counter;
}
const char* get_value(int key) { return _data[key].c_str(); }
int get_ino(const char* name) { return _rev_data[std::string(name)]; }
};
static mutex_map mm;
代码2:(sendmailfs_stat)
static int sendmailfs_stat(fuse_ino_t ino, struct stat* stbuf,
size_t name_length) {
uid_t uid = getuid();
gid_t gid = getgid();
stbuf->st_ino = ino;
if (ino == 1) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
stbuf->st_uid = uid;
stbuf->st_mode = S_IFDIR;
} else {
stbuf->st_mode = S_IFCHR | 0666;
stbuf->st_nlink = 1;
stbuf->st_size = name_length;
stbuf->st_uid = uid;
stbuf->st_gid = gid;
}
return 0;
}
代码3:(readdir回调的实现)
static void ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
struct fuse_file_info* fi) {
// printf("size_t=%ld, fh=%ld, ino=%ld\n", size, fi->fh, ino);
if (ino == 1) {
off_t o = 0;
size_t rest = size;
size_t res;
char* buf = (char*)calloc(1, size);
struct stat dotst;
sendmailfs_stat(ino, &dotst, strlen("."));
res = fuse_add_direntry(req, buf, rest, ".", &dotst, o);
rest -= res;
o++;
printf("%s\n", "start of loop");
uint64_t num_contain = 0;
for (auto& c : mm._data) {
const char* t = c.second.c_str();
int ino2 = mm.get_ino(t);
struct stat st;
sendmailfs_stat(ino2, &st, strlen(t));
fuse_entry_param e;
e.ino = ino2;
e.attr_timeout = 0;
sendmailfs_stat(ino2, &e.attr, strlen(t));
res = fuse_add_direntry_plus(req, buf, rest, t, &e, o);
o += 1;
rest -= res;
}
fuse_reply_buf(req, buf, size);
}
}
【问题讨论】:
-
您似乎已经回答了自己的问题——
ls调用了getdents64,但您还没有提供getdents64函数。 -
或许你应该在当前没有有效回复的情况下回复一些错误?顺便说一句:为什么要为此使用低电平保险丝?还有一件事:您还可以使用
debug选项安装保险丝以获取更多调试信息。
标签: linux filesystems c++ fuse