问题描述
我正在开发示例保险丝应用程序。
在我的应用程序中,使用 touch
命令创建新文件时出现输入/输出错误。
ll_mknod
函数在使用 touch
命令创建文件时被调用。
我该如何解决?
#define FUSE_USE_VERSION 310
#include <fuse3/fuse_lowlevel.h>
#include <cerrno>
#include <cstdio>
#include <cstring>
#include <mutex>
#include <regex>
#include <unordered_map>
struct mutex_map {
int counter = 2;
std::mutex _mtx;
std::unordered_map<int,const char*> _data;
std::unordered_map<const char*,int> _rev_data;
public:
int set_value(const char* value) {
std::lock_guard<std::mutex> lock(_mtx);
counter++;
_data[counter] = value;
return counter;
}
const char* get_value(int key) { return _data[key]; }
int get_ino(const char* name) { return _rev_data[name]; }
};
static mutex_map mm;
static int sendmailfs_stat(fuse_ino_t ino,struct stat* stbuf,size_t name_length) {
stbuf->st_ino = ino;
if (ino == 1) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else {
stbuf->st_mode = S_IFCHR | 0666;
stbuf->st_nlink = 1;
stbuf->st_size = name_length;
}
return 0;
}
static void ll_lookup(fuse_req_t req,fuse_ino_t parent,const char* name) {
struct fuse_entry_param e;
if (parent != 1) {
fuse_reply_err(req,ENOENT);
return;
}
if (mm._rev_data.find(name) == mm._rev_data.end()) {
fuse_reply_err(req,ENOENT);
return;
}
memset(&e,sizeof(e));
int new_ino = mm.set_value(name);
e.ino = (uint64_t)new_ino;
e.attr_timeout = 1.0;
e.entry_timeout = 1.0;
sendmailfs_stat(e.ino,&e.attr,strlen(name));
puts("Helloworld2");
printf("strlen:%zu: %s\n",strlen(name),name);
fuse_reply_entry(req,&e);
}
static void ll_mknod(fuse_req_t req,const char* name,mode_t mode,dev_t rdev) {
if (parent != 1) {
fuse_reply_err(req,ENOENT);
return;
}
std::regex re("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");
if (std::regex_match(name,re)) {
puts("Matched");
int inode_num = mm.set_value(name);
struct fuse_entry_param e;
e.ino = inode_num;
e.attr_timeout = 1.0;
e.entry_timeout = 1.0;
sendmailfs_stat(e.ino,strlen(name));
fuse_reply_entry(req,&e);
} else {
puts("Unmatched");
fuse_reply_err(req,EINVAL);
}
}
static void ll_write(fuse_req_t req,fuse_ino_t ino,const char* buf,size_t size,off_t off,struct fuse_file_info* fi) {
if (mm.get_value(ino) == NULL) {
fuse_reply_err(req,EINVAL);
return;
}
fuse_reply_write(req,size);
}
static void ll_open(fuse_req_t req,struct fuse_file_info* fi) {
if (ino == 1 || !mm.get_value(ino)) {
puts("invalid access due to hello");
fuse_reply_err(req,ENOENT);
} else if ((fi->flags && O_WRONLY)) {
fuse_reply_err(req,EINVAL);
}
fuse_reply_open(req,fi);
}
static void ll_setattr(fuse_req_t req,struct stat* attr,int to_set,struct fuse_file_info* fi) {
puts("setattr");
fuse_reply_err(req,EINVAL);
}
static void ll_setxattr(fuse_req_t req,const char* value,int flags) {
puts("setxattr");
fuse_reply_err(req,EINVAL);
}
static void ll_getattr(fuse_req_t req,struct fuse_file_info* fi) {
puts("getattr");
fuse_reply_err(req,EINVAL);
}
static void ll_getxattr(fuse_req_t req,size_t size) {
puts("getxattr");
fuse_reply_err(req,EINVAL);
}
static const struct fuse_lowlevel_ops opener = {
.lookup = ll_lookup,.mknod = ll_mknod,.open = ll_open,.write = ll_write,};
int main(int argc,char* argv[]) {
struct fuse_args args = FUSE_ARGS_INIT(argc,argv);
struct fuse_session* se;
struct fuse_cmdline_opts opts;
struct fuse_loop_config config;
int ret = -1;
if (fuse_parse_cmdline(&args,&opts) != 0) {
return 1;
}
if (opts.show_help) {
printf("usage: %s [options] <mountpoint>\n\n",argv[0]);
fuse_cmdline_help();
fuse_lowlevel_help();
ret = 0;
goto err_out1;
} else if (opts.show_version) {
printf("FUSE library version %d\n",fuse_version());
fuse_lowlevel_version();
ret = 0;
goto err_out1;
}
if (opts.mountpoint == NULL) {
printf("usage: %s [options] <mountpoint>\n\n",argv[0]);
printf(" %s --help\n",argv[0]);
ret = 1;
goto err_out1;
}
se = fuse_session_new(&args,&opener,sizeof(opener),NULL);
if (fuse_set_signal_handlers(se) != 0) {
goto err_out2;
}
if (fuse_session_mount(se,opts.mountpoint) != 0) {
goto err_out3;
}
fuse_daemonize(opts.foreground);
if (opts.singlethread) {
ret = fuse_session_loop(se);
} else {
config.clone_fd = opts.clone_fd;
config.max_idle_threads = opts.max_idle_threads;
ret = fuse_session_loop_mt(se,&config);
}
fuse_session_unmount(se);
err_out3:
fuse_remove_signal_handlers(se);
err_out2:
fuse_session_destroy(se);
err_out1:
free(opts.mountpoint);
fuse_opt_free_args(&args);
return ret ? 1 : 0;
}
我使用:
Linux 5.12.15
libfuse 3.10.4
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)