当我使用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(因为我不知道驱动程序/控制器的写重新排序语义)。
情景2:
write sector 1 from buffer 1
write sector 500 from buffer 2
write sector 1 from buffer 3
如何处理此方案? 一个更基本的问题是,在使用AIO进行O_DIRECT模式写入时,如果没有明确的写入障碍,这一系列请求是否会在磁盘调度程序的队列中结束? 如果是,是否有任何排序保证,例如“对同一扇区的多次写入将导致最后一次写入是最终写入”? 或者是不确定性的排序[留在磁盘控制器/其缓存的左侧,在屏障内重新排序写入以优化寻道时间]
答案 0 :(得分:3)
障碍是going away。如果您需要在重叠写入之间进行排序,则应该在发出第二个之前等待第一个完成。 (障碍正在消失。)
在一般情况下,我认为没有保证。从应用程序的角度来看,最终结果是不确定的,具体取决于时间,主机和存储设备的状态等。
请求队列将以可预测的方式合并请求,但不要求硬件为同时在驱动器队列中的写入提供一致的结果。
根据存储设备的速度和主机CPU的速度,您不一定能保证在将命令发送到存储设备之前在请求队列中进行合并。
不幸的是,使用O_DIRECT的应用程序(与直接构建bios的文件系统相对)应该等待完成的程序对我来说并不清楚。
答案 1 :(得分:0)
好的,写入请求最终在线性电梯队列中。在这一点上,它们是否来自不同的线程并不相关。相同的安排可能是单个线程发出三次顺序写入的结果。现在,您是否将您的文件信任到操作系统或控制器,以某种任意方式重新排序到同一扇区的顺序写入?我不会,但我当然可能是错的:))