【发布时间】:2019-02-25 14:53:49
【问题描述】:
假设我有一个执行以下操作的简单程序:
fdWrite = open("file", O_WRONLY);
fdRead = open("file", O_RDONLY | O_DIRECT);
writeBuffer = <some data>;
write(fdWrite, writeBuffer);
readBuffer = read(fdRead, sizeof(writeBuffer));
我能保证readBuffer == writeBuffer吗? (显然,鉴于此文件的其他 fd 目前没有打开)
Linux 上的一些简单测试似乎表明,是的,来自 write 调用的脏页将在通过 O_DIRECT 读取之前刷新到磁盘,但我似乎在任何地方都找不到任何提及此场景的内容。据我所知,它的工作可能完全是巧合,而且我不知道在其他类似 POSIX 的平台上会发生什么。至少我想得到一些“确凿的证据”。
你为什么要这样做?
这是在应用程序分发被缓存的大文件的上下文中。收到文件的新部分后,我想验证新部分。我看到使用O_DIRECT 的两个优点:首先,我不仅检查数据是否已正确接收,而且可以从存储介质中正确检索。如果没有O_DIRECT,我几乎可以保证我只是从页面缓存中获取数据。为了在没有O_DIRECT 的情况下达到同样的效果,我必须在Linux 上使用像sync_file_range 这样的不可移植调用来将数据写入磁盘,然后通过madvise 从页面缓存中刷新它,最后再读回它。 (因为我曾经学会了在脏页上用MADV_DONTNEED 调用madvise 本质上是一个无用的方法。
但是,如果有人对此有更优雅的建议,我会全力以赴。 :-)
【问题讨论】:
-
来自 man open(2):“应用程序应避免将 O_DIRECT 和普通 I/O 混合到同一个文件,尤其是同一个文件中的重叠字节区域。即使文件系统正确处理一致性在这种情况下的问题......”。所以看起来它会起作用,但应该避免。
-
这是针对网络文件系统的吗?如果您在单节点机器上执行所有这些操作,那么在时间 t1 写入之后在时间 t2 的任何读取都可以保证提供来自页面缓存的最新数据,而无需 fsync。您是否正在寻找读取的正确性或在磁盘上持久化数据(在这种情况下 fsync 才有意义)?
标签: linux filesystems posix page-caching