FUSE开放系统调用机制

FUSE open system call mechanism

当从程序调用 open 系统调用时,要在 FUSE 管理的目录中创建一个空文件(带有 O_WRONLY | O_CREAT | O_TRUNC),将执行我的 FUSE 文件系统实现中的以下函数:

  1. getattr(returns 错误,因为文件不存在)
  2. create
  3. fgetattr

我的问题是:

这些函数调用是 Linux 中所有文件系统(包括 ext4 等原生文件系统)共有的函数调用,还是 FUSE 内部行为?

strace-ing 程序时,我只能看到一个 open 系统调用。

在花了几天时间研究并盯着 Linux 内核和 FUSE 源代码后,我明白了发生了什么。

首先要说的是fgetattr之后的release不是在执行open系统调用时执行的,而是在调用close时执行的。所以我编辑了我的问题以将其删除。

嗯,我的主要问题是 strace 向我展示了对 open 系统调用的调用,但我的 FUSE 程序日志显示执行了三个函数。因此我对其他文件系统的问题。

Linux kernel documentation中可以看到内核VFS的详细解释:

To look up an inode requires that the VFS calls the lookup() method of the parent directory inode. This method is installed by the specific filesystem implementation that the inode lives in. Once the VFS has the required dentry (and hence the inode), we can do all those boring things like open(2) the file, or stat(2)

在 FUSE 文件系统中,这意味着低级别 API 中的 lookup 调用或高级 API 中的 getattr (因为索引节点路径转换由 libfuse 处理)。用户区代码。其他系统调用,如带有 O_CREAT 标志的 mkdiropen,也需要一个 lookup,在这种情况下确认一个 negative dentry 在做任何事情之前。第 1 点已解决。

The dentry you get should not have an inode (i.e. it should be a negative dentry).

在内核中实现的文件系统,如 ext4,也对 lookup 执行它们的功能。但是您无法使用 常用 工具(例如 strace)从外部看到它们(您需要 kernelshark 之类的东西,很棒的东西)。

ext4 lookup function(我是运行一个Linux3.13内核)

第3点的fgetattr函数调用与libfuse内部更相关。我不知道确切的原因,但 libfuse 在执行 mkdircreate 等函数后执行了 lookup。请记住,lookup 是高级 API 中的 getattr(或创建文件的 fgetattr)。我认为这是由于 file/directory 属性检查所致。

您可以在 libfuse source code 看到它的实际创建功能。

奖励:请记住 FUSE 使用文件属性(和条目)缓存。如果将 -o attr_timeout 挂载选项设置为 0 秒,stat 等一些调用会将两个 getattr 提高到高级别 API。