基于FUSE实现一个文件系统

FUSE

文件系统是一种用来存储和组织计算机文件、目录及其包含的数据的方法,它使文件、目录以及数据的查找和访问得到简化。FUSE(Filesystem in Userspace)是用户级文件系统连接到Linux内核的接口。 使用FUSE我们不需要进行内核级的编程而可以直接创建操作系统。

  • 三大模块
    • 内核模块
    • Libfuse模块
    • 用户程序模块

fuse内核实现VFS接口,传递给libfuse,再传递值用户程序接口进行实现操作

fuse_arch

要使用FUSE来创建一个文件系统,需要声明一个fuse_operations类型的结构变量,并将其传递给fuse_main函数。fuse_operations结构中有一个指针,指向在执行适当操作时需要调用的函数。

struct fuse_operations {
int (*getattr) (const char *, struct stat *);
int (*readlink) (const char *, char *, size_t);
int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
int (*mknod) (const char *, mode_t, dev_t);
int (*mkdir) (const char *, mode_t);
int (*unlink) (const char *);
int (*rmdir) (const char *);
int (*symlink) (const char *, const char *);
int (*rename) (const char *, const char *);
int (*link) (const char *, const char *);
int (*chmod) (const char *, mode_t);
int (*chown) (const char *, uid_t, gid_t);
int (*truncate) (const char *, off_t);
int (*utime) (const char *, struct utimbuf *);
int (*open) (const char *, struct fuse_file_info *);
int (*read) (const char *, char *, size_t, off_t, struct fuse_file_info *);
int (*write) (const char *, const char *, size_t, off_t,struct fuse_file_info *);
int (*statfs) (const char *, struct statfs *);
int (*flush) (const char *, struct fuse_file_info *);
int (*release) (const char *, struct fuse_file_info *);
int (*fsync) (const char *, int, struct fuse_file_info *);
int (*setxattr) (const char *, const char *, const char *, size_t, int);
int (*getxattr) (const char *, const char *, char *, size_t);
int (*listxattr) (const char *, char *, size_t);
int (*removexattr) (const char *, const char *);
};

用户程序实现

  • 获取参数(strtol)
  • 分配空间
  • 读取已有文件
  • fuse_main
    • .getattr
    • .readdir
    • .mkdir
    • .rmdir
    • .read
    • .write
    • .unlink

结构设计

  • name
  • sameLevelNext
  • nextLevelStart
  • nextFileBlockNum
  • type
  • mode
  • dataSize
  • data

设计问题

  • 每个block的大小设置
    • 大了存小文件浪费空间
    • 小了meta data太多浪费空间
  • meta data内的数据(结构设计)
    • 为了简便,所有的的数据都在block内
    • block[0]是/
    • 所有block都必须记录其所在文件的meta data – 浪费空间(考虑比率)
    • 优化:
      • 参考FAT: 建立FAT表和文件表
      • 参考Ext: 多重索引
    • link支持
      • 参考Ext
      • symbolic link: 指向名字
      • hard link: 指向同一个inode
    • 更多文件类型支持(socket)