摘要:
记录FUSE核心流程
总体架构:
FUSE宏观框架
当用户自定义一个新的用户态文件系统被挂载之后,我们在访问该文件系统的文件的方式与访问其他文件系统的文件是一样的,VFS保证了这一点。不同的是,FUSE文件系统下面的访问行为是可以用户自定义的。我们从一个简单的例子出发,先宏观上理解一下整个FUSE工作的流程。
以open为例,整个调用的过程如下:
1- 用户态app调用glibc open接口,触发sys_open系统调用。
2- sys_open 调用fuse中inode节点定义的open方法。
3- inode中open生成一个request消息,并通过/dev/fuse发送request消息到用户态libfuse。
4- Libfuse调用fuse_application用户自定义的open的方法,并将返回值通过/dev/fuse通知给内核。
5- 内核收到request消息的处理完成的唤醒,并将结果放回给VFS系统调用结果。
6- 用户态app收到open的返回结果。
libfuse
Libfuse从fuse_main这个入口开始,从这里我们注册进去定义的文件操作方法来实现我们自己的文件系统。在fuse_main中,首先会完成参数解析,注册用户定义的operations, 实现文件系统的挂载(系统调用mount),填充fuse相关的数据结构,消息的处理。消息的处理部分是libfuse最核心的部分,实现用户态与内核的互动(/dev/fuse),从内核接收req消息,解析,调用用户自定义的ops,完成处理后,把结果通过/dev/fuse返回给内核,内核再返回给VFS层的系统调用,获得结果。
FUSE内核
FUSE内核实现分析
对于内核部分又为两个部分,一个部分是文件系统部分,另一个部分是字符设备部分。两部分建立关联是在文件系统挂载的时候。
接下来我们以删除一个文件为例,看一下FUSE是如何工作的,图2-6摘自libfuse官方文档内核部分。
首先fuse_app会阻塞在读/dev/fuse, 当挂载点下面有新的行为(删除文件)触发时,会通过系统调用调用fuse文件系统内核接口,并生成request消息,同时唤醒阻塞的fuse_app读操作,fuse_app读到request之后,到用户态利用libfuse进行解析,根据request中的opcode找到对应的ops并执行,执行之后通过/dev/fuse把处理的结果传回。VFS阻塞的行为会被唤醒,然后完成VFS的访问。