3

当我使用 O_DIRECT|O_ASYNC 打开一个文件并对同一个磁盘扇区进行两次并发写入,中间没有 fsync 或 fdatasync 时,linux 磁盘子系统或硬件磁盘控制器是否提供任何保证,即该磁盘扇区上的最终数据将是第二个写?

虽然 O_DIRECT 确实绕过了 OS 缓冲区缓存,但数据最终会出现在低级 IO 队列中(磁盘调度程序队列、磁盘驱动程序队列、硬件控制器的缓存/队列等)。我一直跟踪 IO 堆栈到电梯算法。
例如,如果以下请求序列最终出现在磁盘调度程序队列中

write sector 1 from buffer 1  
write sector 2 from buffer 2  
write sector 1 from buffer 3 [Its not buffer 1!!]  

电梯代码将执行“反向合并”以分别从缓冲区 1,2 合并扇区 1,2。然后发出磁盘两个磁盘 IO。但我不确定磁盘扇区 1 上的最终数据是来自缓冲区 1 还是缓冲区 3(因为我不知道驱动程序/控制器的写入重新排序语义)。

场景二:

write sector 1 from buffer 1  
write sector 500 from buffer 2
write sector 1 from buffer 3

这种情况将如何处理?一个更基本的问题是,在使用 AIO 以 O_DIRECT 模式进行写入时,在没有显式写入屏障的情况下,这个请求序列能否最终进入磁盘调度程序的队列?
如果是,是否有任何排序保证,例如“多次写入同一扇区将导致最后一次写入成为最终写入”?
或者是非确定性的排序[任由磁盘控制器/其缓存重新排序障碍内的写入以优化寻道时间]

4

2 回答 2

4

障碍正在消失。如果您需要在重叠写入之间进行排序,则应该等待第一个完成后再发出第二个。(障碍正在消失。)

在一般情况下,我相信没有保证。从应用程序的角度来看,最终结果是不确定的,取决于时间、主机和存储设备的状态等。

请求队列将以可预测的方式合并请求,但硬件不需要同时为驱动器队列中的写入提供一致的结果。

根据存储设备的速度和主机 CPU 的速度,您不一定能保证在命令发送到存储设备之前在请求队列中进行合并。

不幸的是,我不清楚使用 O_DIRECT 的应用程序(而不是直接构建 bios 的文件系统)应该如何等待完成。

于 2010-11-30T22:41:16.990 回答
0

好的,写请求最终进入线性电梯队列。在这一点上,它们是否来自不同的线程并不重要。相同的安排可能是单个线程发出三个顺序写入的结果。现在,您会将您的文件信任给操作系统还是信任以某种任意方式将顺序写入重新排序到同一扇区的控制器?我不会,但我当然可能是错的:)

于 2010-11-30T21:32:46.920 回答