调用 mknod 回调时 FUSE 中的输入/输出错误

问题描述

我正在开发示例保险丝应用程序。

在我的应用程序中,使用 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 (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...