Io 带原始设备fd的fsync

Io 带原始设备fd的fsync,io,filesystems,fsync,Io,Filesystems,Fsync,我对fsync+directio感到困惑 下面的代码很容易理解: fd = open(filename, O_RDWR, 00644); write(fd, data, size); fsync(fd); 在这种情况下,write将数据写入页面缓存,fsync将强制fd引用的页面缓存中的所有修改数据写入磁盘设备 但是如果我们打开一个带有O_DIRECT标志的文件,就像这样 fd = open(filename, O_RDWR|O_DIRECT, 00644); write(fd, data,

我对fsync+directio感到困惑

下面的代码很容易理解:

fd = open(filename, O_RDWR, 00644);
write(fd, data, size);
fsync(fd);
在这种情况下,write将数据写入页面缓存,fsync将强制fd引用的页面缓存中的所有修改数据写入磁盘设备

但是如果我们打开一个带有O_DIRECT标志的文件,就像这样

fd = open(filename, O_RDWR|O_DIRECT, 00644);
write(fd, data, size);
fsync(fd);
在这种情况下,写操作将绕过页缓存,直接写入磁盘设备。那么fsync将做什么呢?fd引用的页面缓存中没有脏页面

如果我们打开一个原始设备,fsync会做什么


在本例中,我们使用O_DIRECT打开一个原始设备,该设备上没有文件系统。同步在这里做什么?

文件系统可能根本不实现O_DIRECT,在这种情况下,它将没有任何效果

如果它确实实现了O_DIRECT,那么这仍然不意味着它会进入磁盘,而是会。它仍然可以缓存在其他地方,甚至在硬件缓冲区中

fsync2是内核和应用程序之间的一个显式连接,用于持久化数据,这样数据就不会丢失,并且保证下一个要访问它的对象可以使用它

对于设备文件,设备驱动程序是实现标志的驱动程序,包括O_DIRECT

Linux确实使用页面缓存来缓存对块设备的访问,并且支持O_DIRECT,以便在直接写入块设备时最小化缓存交互

在这两种情况下,您都需要fsync2或具有同等保证的调用,以确保数据在磁盘上是持久的。

如果我打开一个设备fd=open'/dev/sda',O|RDWR | O|u DIRECT,00644,并将此设备writefd、data、size写入磁盘,如何保证数据实际写入磁盘?fsyncfd在这种情况下会有帮助吗?@Hao假设Linux是,fsync会有帮助,因为它可能会导致设备刷新其易失性缓冲区,但在假设数据在磁盘上之前,您必须先fsync并检查write和fsync返回的代码是否有错误。但是,这假定您是该块设备的唯一写入程序。如果您谈论的是文件系统中的文件,这是另一回事,请参阅答案。
fd = open('/dev/sda', O_RDWR|O_DIRECT, 00644);
write(fd, data, size);
fsync(fd);