如果我使用 libaio + fsync() 会怎样?

What will be if I use libaio + fsync()?

我知道当我使用 write() + fsync()(或 O_SYNC + write() 写文件时,我认为它们是相同的 ref #2),这意味着我正在使用阻塞同步 I/O,如果 write()(with O_SYNC) 或 fsync() returns,则意味着数据安全地在设备介质(例如,用于 SSD 的 TLC NAND)而不是设备缓存(例如,SSD 中的 DDRAM)。

而如果我使用 libaio 呢? (因为我想确保 libaio 发出的写入是在存储介质上而不是设备缓存上。也就是说,我想当 io_getevents() returns 时,它可能无法确保写入在存储上介质,它可能只在设备缓存中)

(本回答只是从Linux的角度来看问题,其他操作系统可能会有不同behaviour/semantics)

只要您等待任何未完成的异步 I/O 完成,您就可以发送您的 fsync() 并知道所有先前的 I/O 已写入稳定存储根据 Linux 内核的最佳知识*.

does fsync() exclusively works for synchronous I/O?

这个问题没有意义。 fsync() 在 I/O 上工作,Linux 同意已“发送”,然后还刷新设备缓存。如果您向内核异步发送 I/O ,内核是否同意它已被“发送”?另见最后一个问题的答案...

is fsync() after io_submit() an undefined behavior?

技术上 undefined behaviour 意味着从那时起任何事情都可以合法发生(例如所谓的鼻腔守护进程)。这里不是这种情况,但我认为你是在问你的第一个问题,所以那里的答案仍然成立。

how to make asynchronous write safely persisted to the device medium rather than device cache (no battery-backed cache).

如果您无法使用 libaio,您可以通过等待所有未完成的 I/O 完成然后发送 fsync() 并等待它或 ( ). Another libaio technique is to set the RWF_SYNC flag during io_submit(). If you were using io_uring 你会有另一个选择,因为你可以使用它的链接并且它有一个异步 fsync 操作 (IORING_OP_FSYNC)。


* 我排除了发生错误的情况,因为它们相当复杂。有关详细说明,请参阅 Writing programs to cope with I/O errors causing lost writes on Linux