经过几天的研究,我对Linux内核和FUSE源代码都有了深入的理解。
首先,我必须说在执行“打开”系统调用时,在fgetattr
之后的release
并没有被执行。因此,我已经编辑了我的问题以删除它。
那么,我的主要问题是strace
显示执行了“打开”系统调用,但是我的FUSE程序日志显示执行了三个函数。因此,我提出了关于其他文件系统的问题。
在Linux kernel documentation 中,我们可以详细了解内核VFS:
要查找一个inode,需要VFS调用其父目录inode的lookup()方法。该方法由inode所在的具体文件系统实现安装。一旦VFS获得所需的dentry(因此获得了inode),我们就可以完成所有这些无聊的事情,例如打开(2)文件或stat(2)。
在FUSE文件系统中,这意味着低级API中的
lookup
调用,或高级API中的
getattr
调用(因为inode-path翻译由libfuse处理)。用户区代码。其他系统调用,如带有
O_CREAT
标志的
mkdir
或
open
也需要进行
lookup
,在这种情况下需要确认负面目录项才能执行任何操作。第一点已解决。
您收到的目录项不应该有inode(即它应该是负目录项)。
像ext4这样实现在内核中的文件系统也使用其功能来执行
lookup
。但是你不能从外部使用
常见的工具(如
strace
)看到它们(你需要像kernelshark这样的工具,非常棒)。
请参阅
ext4查找函数(我正在运行Linux 3.13内核)
第三点的
fgetattr
函数调用与libfuse内部更相关。我不知道确切的原因,但在执行像
mkdir
或
create
这样的函数后,libfuse会执行
lookup
。请记住,
lookup
是高级API中的
getattr
(对于创建的文件是
fgetattr
)。我认为这是由于文件/目录属性检查造成的。
您可以在
libfuse源代码中看到它的实际应用,如create函数。
奖励:请记住,FUSE使用文件属性(和条目)缓存。如果将
-o attr_timeout
挂载选项设置为0秒,则某些调用(例如
stat
)将引发两个
getattr
到高级API。