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