C++实现用户态文件系统 目标与fuse学习(c++用户标识符的命名规则)

2023-03-10 21:23:56

 

排版很乱,慢慢更新目标操作系统实验题预计会采用fuse,protobuf,grpc,C++设想是一个加密的分布式的文件系统打算先实现一个简单本地用户态文件系统再实现一个网络文件系统再实现一个压缩加加密的网络文件系统。

最后完善成分布式文件系统最最后整点特色功能实验要求在现有机器硬盘上开辟100M的硬盘空间,作为设定的硬盘空间编写一管理程序simdisk对此空间进行管理,以模拟Linux文件系统,要求:盘块大小1k空闲盘块的管理:Linux

位图法结构:超级块, i结点区, 根目录区该simdisk管理程序的功能要求如下:info: 显示整个系统信息(参考Linux文件系统的系统信息) cd …: 改变目录 dir …: 显示目录包括文件名、物理地址、保护码、文件长度、子目录等(带/s参数的dir命令,显示所有子目录)md。

…: 创建目录 rd …: 删除目录 newfile …: 建立文件 cat …: 打开文件 copy …: 支持host文件系统与模拟Linux文件系统间的文件拷贝 del …: 删除文件: check

: 检测并恢复文件系统:对文件系统中的数据一致性进行检测,并自动根据文件系统的结构和信息进行数据再整理实现在前端的shell进程和后端的simdisk进程之间利用共享内存进行进程间通信(IPC)实现多个进程同时

对模拟文件系统进行操作。设计管理程序simdisk的用户访问权限管理。学习fuse10. fuse基础知识

文件系统实验参考资料226 浏览 · 2 关注收藏夹

看完我的收藏夹就明白很多啦还有这个人的文章qiya:自制文件系统 — 01 文件系统的样子47 赞同 · 5 评论文章不过他的是Go语言,不太懂......在github上也有适用于windows系统的fuse。

但是我用的是github上的libfuse,主要适用与ubuntu此外wsl目前不支持fuse(/lib/modules目录为空)可能需要自己编译内核才行......推荐买个ubuntu的云服务器就好下文基本是是对

Writing a Simple Filesystem Using FUSE in C​www.maastaar.net/fuse/linux/filesystem/c/2016/05/21/writing-a-simple-filesystem-using-fuse/

的学习过程记录和一些补充(因为新老版本有点不一样,有些地方。)直接看原文最好啦。接下来上手写代码。因为

所以#define FUSE_USE_VERSION 31 //我这里是31,按情况写 #include#include#include#include

#include#include#includeWriting a Simple Filesystem Using FUSE in C

​www.maastaar.net/fuse/linux/filesystem/c/2016/05/21/writing-a-simple-filesystem-using-fuse/getattr是最必须实现的。

所以先看getattr1. 实现getattrthe function of this event is going to return important information about each file that resides in our filesystem by filling a structure of type

statint(*getattr)(constchar*,structstat*);//这是文章老版本的fuse int(*getattr)(constchar*,structstat*,structfuse_file_info

*fi);//这是我的版本stat(2) - Linux manual page​man7.org/linux/man-pages/man2/stat.2.htmlThe first parameter is the path of the file which the system asked SSFS for its attributes. The other parameter is the “stat” structure which must be filled with the attributes of that file. On success the return value must be 0, otherwise it is -1 and “errno” must be filled with the right error code.

接受一个文件路径,通过struct stat返回文件属性成功返回值为0st->st_uid=getuid();st->st_gid=getgid();st->st_atime=time(NULL);st

->st_mtime=time(NULL);We use the functions getuid and getgid to get the user id and group id of the current user (the user who mounted the filesystem).

后两个必须是Unix 时间acess time, modify timeif ( strcmp( path, "/" ) == 0 ) { st->st_mode = S_IFDIR | 0755; st->st_nlink = 2; } else { st->st_mode = S_IFREG | 0644; st->st_nlink = 1; st->st_size = 1024; } return 0;。

As you can see from the last piece of code that we fill both “st_mode” and “st_nlink” fields with different information according to the path of the file in question. The field “st_mode” specifies if the file is a regular file, directory or

other. In addition, “st_mode” specifies the permission bits of that file. The field “st_nlink” specifies the number of

hardlinks. Finally, the field “st_size” specifies the size of that file in bytes.st_mode指明是文件还是目录或者其它。

st_nlink指明硬链接的数量st_size文件大小宏S_IFDIR表示是一个目录后面或的是权限位权限可以参考下面的链接Understanding Linux File Permissions - Linux.com。

​www.linux.com/training-tutorials/understanding-linux-file-permissions/755表示文件拥有者可以读写执行,其他人不能写宏S_IFREG类似,表示是一个常规文件。

为什么目录的st_nlink是二呢?因为Theres one for the directory itself, and one for.inside it.ls - Why does a new directory have a hard link count of 2 before anything is added to it? - Unix & Linux Stack Exchange

​unix.stackexchange.com/questions/101515/why-does-a-new-directory-have-a-hard-link-count-of-2-before-anything-is-added-to/101536#101536

最终的样例staticintdo_getattr(constchar*path,structstat*st)//static int do_getattr( const char *path, struct stat *st, struct fuse_file_info *fi )

{printf("[getattr] Called\n");printf("\tAttributes of %s requested\n",path);// GNUs definitions of the attributes (http://www.gnu.org/software/libc/manual/html_node/Attribute-Meanings.html):

// st_uid: The user ID of the file’s owner. // st_gid: The group ID of the file. // st_atime: This is the last access time for the file.

// st_mtime: This is the time of the last modification to the contents of the file. // st_mode: Specifies the mode of the file. This includes file type information (see Testing File Type) and the file permission bits (see Permission Bits).

// st_nlink: The number of hard links to the file. This count keeps track of how many directories have entries for this file. If the count is ever decremented to zero, then the file itself is discarded as soon

// as no process still holds it open. Symbolic links are not counted in the total. // st_size: This specifies the size of a regular file in bytes. For files that are really devices this field isn’t usually meaningful. For symbolic links this specifies the length of the file name the link refers to.

st->st_uid=getuid();// The owner of the file/directory is the user who mounted the filesystem st->st_gid

=getgid();// The group of the file/directory is the same as the group of the user who mounted the filesystem

st->st_atime=time(NULL);// The last "a"ccess of the file/directory is right now st->st_mtime=time(NULL

);// The last "m"odification of the file/directory is right now if(strcmp(path,"/")==0){st->st_mode=S_IFDIR

|0755;st->st_nlink=2;// Why "two" hardlinks instead of "one"? The answer is here: http://unix.stackexchange.com/a/101536

}else{st->st_mode=S_IFREG|0644;st->st_nlink=1;st->st_size=1024;}return0;}2. 实现readdirreaddir列出目录下所有文件和目录

//文章的版本 intreaddir(constchar*path,void*buffer,fuse_fill_dir_tfiller,off_toffset,structfuse_file_info*

fi)//现在的版本 intreaddir(constchar*path,void*buffer,fuse_fill_dir_tfiller,off_toffset,structfuse_file_info

*fi,enumfuse_readdir_flags);多了个flag

不知道干什么的,当作不存在就好(大概没问题吧,也许)。我们只关注三个参数。第一个参数path是读哪个目录。第二个参数buffer是结果要放到的地方。第三个参数filler是怎么放。

typedefint(*fuse_fill_dir_t)(void*buf,constchar*name,conststructstat*stbuf,off_toff,enumfuse_fill_dir_flags

flags);可见filler是个函数The first parameter is a pointer to the buffer which we want to write the entry (filename or directory name) on. The second parameter is the name of the current entry. The third and the fourth parameters will not be covered here.。

emmm第五个参数也不管了

上图在fuse.h文件filler(buffer,".",NULL,0);//当前目录 filler(buffer,"..",NULL,0);//上级目录 if(strcmp(path,"/")==0)

{// 如果查询的是根目录,展示下面两个文件 filler(buffer,"file54",NULL,0,FUSE_FILL_DIR_PLUS);filler(buffer,"file349",NULL

,0,FUSE_FILL_DIR_PLUS);}return0;完整代码staticintdo_readdir(constchar*path,void*buffer,fuse_fill_dir_tfiller

,off_toffset,structfuse_file_info*fi,enumfuse_readdir_flags){printf("--> Getting The List of Files of %s

\n",path);filler(buffer,".",NULL,0,FUSE_FILL_DIR_PLUS);// Current Directory filler(buffer,"..",NULL,0

,FUSE_FILL_DIR_PLUS);// Parent Directory if(strcmp(path,"/")==0)// If the user is trying to show the files/directories of the root directory show the following

{filler(buffer,"file54",NULL,0,FUSE_FILL_DIR_PLUS);filler(buffer,"file349",NULL,0,FUSE_FILL_DIR_PLUS);

}return0;}实现了两个函数了,先编译一下看看什么情况这是目前的完整代码/* * 这是fuse-3.10.4版本的,老版本的代码参考文章开头的链接 * gcc -Wall main.cpp `pkg-config fuse3 --cflags --libs` -o myfs 。

*/#define FUSE_USE_VERSION 31 #include#include#include#include

#include#include#includestaticintdo_getattr(constchar*path,structstat*st,

structfuse_file_info*fi){printf("[getattr] Called\n");printf("\tAttributes of %s requested\n",path);// GNUs definitions of the attributes (http://www.gnu.org/software/libc/manual/html_node/Attribute-Meanings.html):

// st_uid: The user ID of the file’s owner. // st_gid: The group ID of the file. // st_atime: This is the last access time for the file.

// st_mtime: This is the time of the last modification to the contents of the file. // st_mode: Specifies the mode of the file. This includes file type information (see Testing File Type) and the file permission bits (see Permission Bits).

// st_nlink: The number of hard links to the file. This count keeps track of how many directories have entries for this file. If the count is ever decremented to zero, then the file itself is discarded as soon

// as no process still holds it open. Symbolic links are not counted in the total. // st_size: This specifies the size of a regular file in bytes. For files that are really devices this field isn’t usually meaningful. For symbolic links this specifies the length of the file name the link refers to.

st->st_uid=getuid();// The owner of the file/directory is the user who mounted the filesystem st->st_gid

=getgid();// The group of the file/directory is the same as the group of the user who mounted the filesystem

st->st_atime=time(NULL);// The last "a"ccess of the file/directory is right now st->st_mtime=time(NULL

);// The last "m"odification of the file/directory is right now if(strcmp(path,"/")==0){st->st_mode=S_IFDIR

|0755;st->st_nlink=2;// Why "two" hardlinks instead of "one"? The answer is here: http://unix.stackexchange.com/a/101536

}else{st->st_mode=S_IFREG|0644;st->st_nlink=1;st->st_size=1024;}return0;}staticintdo_readdir(constchar

*path,void*buffer,fuse_fill_dir_tfiller,off_toffset,structfuse_file_info*fi,enumfuse_readdir_flags){printf

("--> Getting The List of Files of %s\n",path);filler(buffer,".",NULL,0,FUSE_FILL_DIR_PLUS);// Current Directory

filler(buffer,"..",NULL,0,FUSE_FILL_DIR_PLUS);// Parent Directory if(strcmp(path,"/")==0)// If the user is trying to show the files/directories of the root directory show the following

{filler(buffer,"file54",NULL,0,FUSE_FILL_DIR_PLUS);filler(buffer,"file349",NULL,0,FUSE_FILL_DIR_PLUS);

}return0;}staticconststructfuse_operationsmy_oper={.getattr=do_getattr,.readdir=do_readdir};intmain(int

argc,char*argv[]){intret;structfuse_argsargs=FUSE_ARGS_INIT(argc,argv);ret=fuse_main(args.argc,args.argv

,&my_oper,NULL);returnret;}使用命令gcc -Wall main.cpp `pkg-config fuse3 --cflags --libs` -o myfs然后mkdir test ./myfs ./test #./myfs + 要挂载在哪里

没反应就对了。然后df -ahT可以看的最后一个就是

然后进去试试ls命令

成功了。试试别的

都不行。less报错 read error。下一步实现read吧。

接下来umount它

通过df -ahT可以看到已经没有了文件系统的第一小步完成了3. 实现readintread(constchar*path,char*buffer,size_tsize,off_toffset,struct。

fuse_file_info*fi)// 新老版本一致 第一个参数“path”是系统想要读取的文件路径在第二个参数“buffer”中,要存储系统想要的chunk,第三个参数“size”表示该chunk的大小,第四个参数“offset”是文件内容中我们将要开始读取的位置。

最后必须return已成功读取的字节数首先定义charfile54Text[]="Hello World From File54!";charfile349Text[]="Hello World From File349!"

;char*selectedText=NULL;do_read中可以这样写if(strcmp(path,"/file54")==0)selectedText=file54Text;elseif(strcmp

(path,"/file349")==0)selectedText=file349Text;elsereturn-1;memcpy(buffer,selectedText+offset,size);//对应内容放到buff

returnstrlen(selectedText)-offset;//返回读取的字节数 完整do_readstaticintdo_read(constchar*path,char*buffer,size_t

size,off_toffset,structfuse_file_info*fi){charfile54Text[]="Hello World From File54!";charfile349Text

[]="Hello World From File349!";char*selectedText=NULL;if(strcmp(path,"/file54")==0)selectedText=file54Text

;elseif(strcmp(path,"/file349")==0)selectedText=file349Text;elsereturn-1;memcpy(buffer,selectedText+offset

,size);returnstrlen(selectedText)-offset;}目前的完整代码/* * gcc -Wall main.cpp `pkg-config fuse3 --cflags --libs` -o myfs

*/#define FUSE_USE_VERSION 31 #include#include#include#include

#include#include#includestaticintdo_getattr(constchar*path,structstat*st,

structfuse_file_info*fi){printf("[getattr] Called\n");printf("\tAttributes of %s requested\n",path);// GNUs definitions of the attributes (http://www.gnu.org/software/libc/manual/html_node/Attribute-Meanings.html):

// st_uid: The user ID of the file’s owner. // st_gid: The group ID of the file. // st_atime: This is the last access time for the file.

// st_mtime: This is the time of the last modification to the contents of the file. // st_mode: Specifies the mode of the file. This includes file type information (see Testing File Type) and the file permission bits (see Permission Bits).

// st_nlink: The number of hard links to the file. This count keeps track of how many directories have entries for this file. If the count is ever decremented to zero, then the file itself is discarded as soon

// as no process still holds it open. Symbolic links are not counted in the total. // st_size: This specifies the size of a regular file in bytes. For files that are really devices this field isn’t usually meaningful. For symbolic links this specifies the length of the file name the link refers to.

st->st_uid=getuid();// The owner of the file/directory is the user who mounted the filesystem st->st_gid

=getgid();// The group of the file/directory is the same as the group of the user who mounted the filesystem

st->st_atime=time(NULL);// The last "a"ccess of the file/directory is right now st->st_mtime=time(NULL

);// The last "m"odification of the file/directory is right now if(strcmp(path,"/")==0){st->st_mode=S_IFDIR

|0755;st->st_nlink=2;// Why "two" hardlinks instead of "one"? The answer is here: http://unix.stackexchange.com/a/101536

}else{st->st_mode=S_IFREG|0644;st->st_nlink=1;st->st_size=1024;}return0;}staticintdo_readdir(constchar

*path,void*buffer,fuse_fill_dir_tfiller,off_toffset,structfuse_file_info*fi,enumfuse_readdir_flags){printf

("--> Getting The List of Files of %s\n",path);filler(buffer,".",NULL,0,FUSE_FILL_DIR_PLUS);// Current Directory

filler(buffer,"..",NULL,0,FUSE_FILL_DIR_PLUS);// Parent Directory if(strcmp(path,"/")==0)// If the user is trying to show the files/directories of the root directory show the following

{filler(buffer,"file54",NULL,0,FUSE_FILL_DIR_PLUS);filler(buffer,"file349",NULL,0,FUSE_FILL_DIR_PLUS);

}return0;}staticintdo_read(constchar*path,char*buffer,size_tsize,off_toffset,structfuse_file_info*fi)

{charfile54Text[]="Hello World From File54!";charfile349Text[]="Hello World From File349!";char*selectedText

=NULL;if(strcmp(path,"/file54")==0)selectedText=file54Text;elseif(strcmp(path,"/file349")==0)selectedText

=file349Text;elsereturn-1;memcpy(buffer,selectedText+offset,size);returnstrlen(selectedText)-offset;}

staticconststructfuse_operationsmy_oper={// 这里注意顺序要和fuse.h里的顺序一致 .getattr=do_getattr,.read=do_read,.readdir

=do_readdir,};intmain(intargc,char*argv[]){intret;structfuse_argsargs=FUSE_ARGS_INIT(argc,argv);ret=fuse_main

(args.argc,args.argv,&my_oper,NULL);returnret;}And we got our first filesystem! :-)To mount the filesystem after compilation:

gcc -Wall main.cpp `pkg-config fuse3 --cflags --libs` -o myfs ./myfs -f [mount point]Using the option “-f” will let you see the debug messages which are printed using “printf”.

原来要加-f才有printf输出啊。

然后在另一个窗口操作文件系统

原来的less也OK了

原文作者使用的是2.9.4我用的是3.10.4这是2.9.4的代码fuse学习2感觉经过fuse学习1之后已经基本掌握了,上面这篇大略扫一遍就够了,所以就不写好了,经过学习我们已经熟悉fuse的api了。

接下来就是设计我们的文件系统了最简单的一个fuse文件系统需要支持以下apistaticstructfuse_operationsdhmp_fs_oper={.getattr.readdir.mknod

.mkdir.rmdir.rename.read.write.statfs};函数的接口void*(*init)(structfuse_conn_info*conn,structfuse_config*

cfg)int(*getattr)(constchar*,structstat*,structfuse_file_info*fi)int(*mknod)(constchar*,mode_t,dev_t)

int(*mkdir)(constchar*,mode_t)int(*rmdir)(constchar*)int(*rename)(constchar*,constchar*,unsignedintflags

)int(*read)(constchar*,char*,size_t,off_t,structfuse_file_info*)int(*write)(constchar*,constchar*,size_t

,off_t,structfuse_file_info*)int(*statfs)(constchar*,structstatvfs*)int(*readdir)(constchar*,void*,fuse_fill_dir_t

,off_t,structfuse_file_info*,enumfuse_readdir_flags)需要了解 fuse_fill_dir_t, fuse_file_info, fuse_conn_info, fuse_config, mode_t, fuse_readdir_flags。


以上就是关于《C++实现用户态文件系统 目标与fuse学习(c++用户标识符的命名规则)》的全部内容,本文网址:https://www.7ca.cn/baike/3521.shtml,如对您有帮助可以分享给好友,谢谢。
标签:
声明

排行榜