用fuse构建自己的文件系统(指南篇)

0.适合学完操作系统课程还未做过课设的同学阅读

在CSDN上搜索同名文章,大多是一些fuse的介绍,以及各自的复杂fuse和RPC对接实现,初学来看可能还是不知道怎么动手写代码,所以写点自己的理解。本文基于内存文件系统来写,无权限控制,尽可能简化文件系统功能来快速做一个demo。

本科时候用C写过一个完整的文件系统小系统(./a.out执行后才进入文件系统),其功能大致可以分为下图几个部分。

用fuse构建自己的文件系统(指南篇)_第1张图片

1.FUSE基础知识了解(其他博客)

2.FUSE已经做了什么

用fuse构建自己的文件系统(指南篇)_第2张图片

对比前后两图,可以看到FUSE已经完成了各级目录的显示输出,已经申明了一些函数接口,即已经告诉你有一些具有特定功能的函数,但是功能的具体实现需要程序员自己设定。定义函数如下:

struct fuse_operations {
int (*getattr) (const char *, struct stat *);
int (*readlink) (const char *, char *, size_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 statvfs *);
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 *);
int (*opendir) (const char *, struct fuse_file_info *);
int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *);
int (*releasedir) (const char *, struct fuse_file_info *);
int (*fsyncdir) (const char *, int, struct fuse_file_info *);
void *(*init) (struct fuse_conn_info *conn);
void (*destroy) (void *);
int (*access) (const char *, int);
int (*create) (const char *, mode_t, struct fuse_file_info *);
int (*ftruncate) (const char *, off_t, struct fuse_file_info *);
int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *);
int (*lock) (const char *, struct fuse_file_info *, int cmd, struct flock *);
int (*utimens) (const char *, const struct timespec tv[2]);
int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
};

比如,已经申明了open,read,write函数,功能是打开文件,向文件中读取写入数据。具体实现则有程序员自己定义,可以定义成所有的open都返回同一个文件,而read,write也无视输入的参数而随意选定一个文件读取任意size的数据。FUSE不管你的函数具体怎么做,只在用户发出指令的时候调用固定函数,然后看函数返回值(这个也是你定义的,为了正确对接需要看FUSE设定的返回值各有什么含义)有没有问题。

经过试验,完成一个最简易的FUSE文件系统,需要实现的函数有

static struct fuse_operations dhmp_fs_oper = {
	.getattr	
	.readdir	
	.mknod		
	.mkdir	
	.rmdir		
	.rename	
	.read	
	.write	
	.statfs		
};

为了在挂载后能将文件复制进FUSE文件系统并查看是否出错,以上是需要实现的函数组(可能更少)。接下来就是把这些函数填满就行了,可以看到里面包含对文件的读取写入,同时创建删除操作会修改元数据,(这里去掉了access和open等,取消了权限判断)。

3.最简易实现

这个demo不支持什么:没有权限、没有用户、没有硬软链接等等。

这个demo有什么用:写这个demo完全是为了跟自定义的malloc对接(也就是数据存储使用自定义的malloc来开辟内存),跑一些实验啥的。已知可以把mongodb、hadoop、caffe等放进去跑基准测试。

在这个demo往上继续添加权限等东西,自由度很高,目的更多地是作为一个指南发出来,一个都能理解的基础的内存文件系统demo可以在实践层面方便初学FUSE的人入门。

github链接:https://github.com/Lhoddy/FUSEdemo

你可能感兴趣的:(实验测试)