FUSE - 避免在 GetAttr 中计算大小

ita*_*ysk 5 fuse go

我正在为远程服务实现 FUSE 文件系统。当用户打开文件时,我会进行网络调用以获取文件的内容。似乎必须报告文件的大小GetAttr才能打开工作。
为了知道文件的大小,我必须发出网络调用,并且由于GetAttr在执行时为每个条目调用ls,因此我担心这种设计(如果用户ls在包含许多项目的目录中进行操作,则必须获取所有文件,即使用户不想打开任何文件)。

我该如何解决这个问题?我的想法是:

  • 使用不依赖于报告大小的较低级别的读取方法?我认为使用Read而不是Open可能会有所帮助,但是如果没有尺寸我就无法让它工作。
  • 如果我能区分GetAttr源自呼叫Open其他电话(含ls),我可能只在需要时发出的网络调用。

我使用 Go 和go-fuse,但我认为这无关紧要,因为这是一个通用的 FUSE 问题。

此外,FUSE 文档非常少(实际上缺少)文档。如果熟悉此事的人可以解释ls,cdcat- 以何种顺序调用哪些 FUSE 函数的调用流程,那就太好了。
例如,为什么同时存在OpenRead

更新:
我一直在浏览 SSHFS,它被认为是 FUSE 文件系统的规范示例,它似乎也在 getattr 上通过网络获取文件:https : //github.com/libfuse/sshfs/blob/master/sshfs .c#L3167
你怎么看?

lny*_*yng 1

您看到的问题是因为内核正在缓冲您的读取,当它这样做时,它使用 inode 的大小来准确计算它必须复制到用户空间的字节数(https://elixir.bootlin.com /linux/v4.19.7/source/mm/filemap.c#L2137)。因此有不同的解决方法:

  1. 从 GetAttr 返回巨大的 st_size

  2. 打开文件时,设置 direct_io 标志,这样就不会使用页面缓存。