在 FUSE 文件系统上的 mkdir 期间,lstat 错误“不允许操作”

问题描述

我有一个应该创建目录的 FUSE 文件系统的简单实现。当我使用 -d 选项挂载它时,我注意到在 mkdir newdir 上它失败并且我收到错误 Operation not permitted 因为 mkddir 熔丝操作在我尝试的新目录上调用 getattr() 函数create 因此 lstat 失败,因为该目录尚不存在(尚未创建)。 mkdir new_dir 上的调试输出

LOOKUP /new_dir
getattr[NULL] /new_dir
[getattr] file: /home/mrima/mifuse/root/new_dir
        
lstat error
   unique: 246,error: -1 (Operation not permitted),outsize: 16

我觉得我的实现中缺少一些非常基本的东西。我该如何解决这个问题?

这是我的代码

#define FUSE_USE_VERSION 30
#include <fuse.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>


#define BB_DATA ((struct mi_state *) fuse_get_context()->private_data)
struct mi_state{
    char *root_dir;
};


static void mi_fullpath(char fpath[PATH_MAX],const char *path)
{
    strcpy(fpath,BB_DATA->root_dir);
    strncat(fpath,path,PATH_MAX);
}

static int mi_getattr(const char *path,struct stat *st)
{
    int res;

    char fpath[PATH_MAX];
    mi_fullpath(fpath,path);

    printf("[getattr] file: %s\n",fpath);

    res = lstat(fpath,st);
    if (res != 0)
        printf("\t\t\nlstat error\n\t");

    return res;
}


static int do_readdir(const char *path,void *buf,fuse_fill_dir_t filler,off_t offset,struct fuse_file_info *fi)
{
    (void) offset;
    (void) fi;
    char fpath[PATH_MAX];
    mi_fullpath(fpath,path);
    printf("[readdir] %s\n",fpath);
    struct dirent *dir;
    DIR *dr = opendir(fpath);
    if (dr == NULL)
        return -ENOMEM;

    do {
        if (filler(buf,dir->d_name,NULL,0) != 0) {
            return -ENOMEM;
        }
    } while ((dir = readdir(dr)) != NULL);

    return 0;
}



static int do_mkdir(const char *path,mode_t mode)
{
    char fpath[PATH_MAX];
    mi_fullpath(fpath,path);
    return mkdir(fpath,mode);
}

int mi_statfs(const char *path,struct statvfs *statv)
{
    int retstat = 0;
    char fpath[PATH_MAX];
    mi_fullpath(fpath,path);

    // get stats for underlying filesystem
    retstat = statvfs(fpath,statv);
    return retstat;
}
void *mi_init()
{
    fuse_get_context();
    return BB_DATA;
}


static struct fuse_operations fuse_example_operations = {
        .getattr = mi_getattr,.readdir = do_readdir,.mkdir   = do_mkdir,.init    = mi_init,.statfs  = mi_statfs,};


void mifuse_usage()
{
    fprintf(stderr,"usage:  ./mfuse [FUSE and mount options] rootDir mountPoint\n");
    abort();
}

int main(int argc,char *argv[]){
    struct mi_state *mi_data;

    if ((getuid() == 0) || (geteuid() == 0)) {
        fprintf(stderr,"Running MiFUSE as root opens unnacceptable security holes\n");
        return 1;
    }
    if ((argc < 3) || (argv[argc-2][0] == '-') || (argv[argc-1][0] == '-'))
        mifuse_usage();
    fprintf(stderr,"Fuse library version %d.%d\n",FUSE_MAJOR_VERSION,FUSE_MInor_VERSION);

    mi_data = malloc(sizeof(struct mi_state));
    if (mi_data == NULL) {
        perror("main calloc");
        abort();
    }
    mi_data->root_dir = realpath(argv[argc - 2],NULL);
    argv[argc-2] = argv[argc-1];
    argv[argc-1] = NULL;
    argc--;
    return fuse_main(argc,argv,&fuse_example_operations,mi_data);
}

我用 gcc -Wall main.c ``pkg-config fuse3 --cflags --libs`` -o hello

编译它

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

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