Linux 通过O_直接阅读是否会首先刷新脏页?

Linux 通过O_直接阅读是否会首先刷新脏页?,linux,filesystems,posix,page-caching,Linux,Filesystems,Posix,Page Caching,假设我有一个简单的程序,可以执行以下操作: fdWrite = open("file", O_WRONLY); fdRead = open("file", O_RDONLY | O_DIRECT); writeBuffer = <some data>; write(fdWrite, writeBuffer); readBuffer = read(fdRead, sizeof(writeBuffer)); fdWrite=open(“文件”,仅限O_write); fdRead=打开

假设我有一个简单的程序,可以执行以下操作:

fdWrite = open("file", O_WRONLY);
fdRead = open("file", O_RDONLY | O_DIRECT);
writeBuffer = <some data>;
write(fdWrite, writeBuffer);
readBuffer = read(fdRead, sizeof(writeBuffer));
fdWrite=open(“文件”,仅限O_write);
fdRead=打开(“文件”,O|u RDONLY | O|u DIRECT);
writeBuffer=;
写入(fdWrite,writeBuffer);
readBuffer=read(fdRead,sizeof(writeBuffer));
我是否可以保证
readBuffer==writeBuffer
?(显然,该文件当前没有打开其他fd)

Linux上的一些简单测试似乎表明,是的,写入调用中的脏页将在通过
O_DIRECT
读取之前刷新到磁盘,但我似乎在任何地方都找不到任何关于此场景的提及。据我所知,这可能是一个完全巧合,它的工作,我不知道会发生什么在其他POSIX类似的平台。我想至少得到一些关于这件事的“确凿证据”

你为什么要这样做?

它位于一个应用程序的上下文中,该应用程序分发被缓存的大型文件。一旦收到文件的新部分,我想验证新部分。我认为使用
O_DIRECT
有两个优点:首先,我不仅检查数据是否正确接收,而且可以从存储介质中正确检索数据。没有
O_DIRECT
我几乎可以保证我只是从页面缓存中获取数据。为了在没有
O_DIRECT
的情况下实现同样的效果,我必须在Linux上使用像
sync_file_range
这样的不可移植调用将数据获取到磁盘,然后通过
madvise
从页面缓存中刷新数据,最后将其读回。(因为我曾经艰难地学会了在脏页上用
MADV_DONTNEED
调用
madvise
基本上是一个noop)。
但如果有人对此有更优雅的建议,我洗耳恭听。:-)

我不仅要检查数据是否正确接收,而且要检查数据是否可以从存储介质中正确检索

要做到这一点,您需要消除设备所做的缓存

大多数设备数据缓存相对较小—兆字节而不是千兆字节。[*]如果您的大文件足够大,您可以执行write()+fsync(),这样会使设备缓存溢出。然后使用您的DONTNEED将其从Linux页面缓存中删除。然后可以从设备上重新读取()文件


[*]一些虚拟化环境打破了这一预期

来自man open(2):“应用程序应避免将O_DIRECT和普通I/O混合到同一文件中,尤其是同一文件中的重叠字节区域。即使文件系统在这种情况下正确处理了一致性问题……”。所以它看起来可以工作,但应该避免。这是针对网络文件系统的吗?如果您在单节点机器上执行所有这些操作,那么在时间t1写入之后在时间t2进行的任何读取都可以保证提供来自页面缓存的最新数据,而不需要fsync。您是否在寻找磁盘上读取或持久化数据的正确性(在这种情况下,fsync是有意义的)?