使用FUSE在C中编写一个简单的文件系统

时间:2014-04-22 01:06:12

标签: c linux operating-system fuse

我已经学会了hello.c。 它可以在mountfile下创建一个hello文件。 但我不知道如何在mountfile下创建一个文件夹,然后在mountfile / folderIcreate下创建hello。 然后我可以使用cat mountfile / folderIcreate / hello 代码类似于简单的hello.c

#define FUSE_USE_VERSION 30

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

static const char *hello_str = "Hello World!\n";
static const char *add_path = "/add";
static const char *div_path = "/div";
static const char *hello_path = "/hello";

static int hello_getattr(const char *path, struct stat *stbuf)
{
    int res = 0;

    printf("%s", path);

    memset(stbuf, 0, sizeof(struct stat));
    if (strcmp(path, "/") == 0) 
    {
        stbuf->st_mode = S_IFDIR | 0755;
        stbuf->st_nlink = 2;
    } 
    else if (strcmp(path, hello_path) == 0) 
    {
        stbuf->st_mode = S_IFREG | 0444;
        stbuf->st_nlink = 1;
        stbuf->st_size = strlen(hello_str);
    }
    else if (strcmp(path, add_path) == 0) 
    {
        stbuf->st_mode = S_IFDIR | 0755;
        stbuf->st_nlink = 3;
        if (strcmp(path, add_path1) == 0) 
        {
            stbuf->st_mode = S_IFREG | 0444;
            stbuf->st_nlink = 1;
            stbuf->st_size = strlen(hello_str);
        }
    }
    else if(strcmp(path, div_path) == 0)
    {
        stbuf->st_mode = S_IFDIR | 0755;
        stbuf->st_nlink = 3;
    } 
    else if(strcmp(path, div_path) == 0)
    {
        stbuf->st_mode = S_IFDIR | 0755;
        stbuf->st_nlink = 3;
    } 
    else
        res = -ENOENT;

    return res;
}

static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
         off_t offset, struct fuse_file_info *fi)
{
    printf("%s", path);
    (void) offset;
    (void) fi;

    if (strcmp(path, "/") != 0)
        return -ENOENT;

    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    filler(buf, hello_path + 1, NULL, 0);
    filler(buf, add_path + 1, NULL, 0);
    filler(buf, div_path + 1, NULL, 0);

    return 0;
}

static int hello_open(const char *path, struct fuse_file_info *fi)
{
    printf("%s", path);
    if (strcmp(path, hello_path) != 0)
        return -ENOENT;

    if ((fi->flags & 3) != O_RDONLY)
        return -EACCES;

    return 0;
}

static int hello_read(const char *path, char *buf, size_t size, off_t offset,
          struct fuse_file_info *fi)
{
    printf("%s", path);
    size_t len;
    (void) fi;
    if(strcmp(path, hello_path) != 0)
        return -ENOENT;

    len = strlen(hello_str);
    if (offset < len) {
        if (offset + size > len)
            size = len - offset;
        memcpy(buf, hello_str + offset, size);
    } else
        size = 0;

    return size;
}

static struct fuse_operations hello_oper = {
    .getattr    = hello_getattr,
    .readdir    = hello_readdir,
    .open       = hello_open,
    .read       = hello_read,
};

int main(int argc, char *argv[])
{
    return fuse_main(argc, argv, &hello_oper, NULL);
}

有人可以给出一个简单的例子,说明如何在不改变struct fuse_operations的情况下修改上面的代码。 谢谢!

1 个答案:

答案 0 :(得分:1)

要使目录在FUSE文件系统中正常工作,需要满足以下条件:

  • 目录需要stat() - 能够,并且应该返回适​​合目录的属性(例如,可读,可执行和S_IFDIR)。

  • 目录必须为readdir() - 能够。

  • 目录需要显示在其父级的readdir()列表中。 (这在某种程度上是可选的,但在列表中出现 not 目录是不寻常的,并且会使其难以访问!)

  • 目录下的所有新路径都必须stat()能够open() / read(),如果合适的话。

这些都不是新的操作;它们只是现有的扩展。如果您对如何进行某些更改有特定问题,请澄清您的问题。