Why I/O Error causes when I tried ls . command in my fuse filesystem?
My filesystem has a limitation that it only allows mail address type as individual filename and it does not allows sub directory.
Now I want to display a list of file name when use ls . but it does not work.
I understood that it must implement a callback function. (Correspond function is ll_readdir in mycode)
but I have no idea what points are causes the errors.
Update:
Now I use strace command to investigate what system call raise a this error.
According to result of strace, this error caused in getdents64 syscall.
getdents64(3, 0x5611ed000540, 32768) = -1 EIO (Input/output error)
Code1 (implementation of 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;
Code2: (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;
}
Code 3: (implementation of readdir callback)
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);
}
}