使用O_DIRECT打开文件后执行'write'操作后的用户缓冲区

3

我正在使用O_DIRECT标志,从用户缓冲区直接写入磁盘。但就我所知,Linux不保证此调用后数据已被写入。它只是使用DMA或其他方法,将数据直接从用户缓冲区写入物理设备...因此,我不明白在'写入'函数调用后是否可以向用户缓冲区写入。

我相信示例代码将有助于理解我的问题:

char *user_buff = malloc(...); /* assume it is aligned as needed */
fd = open(..., O_DIRECT);
write(fd, ...)
memset(user_buff, 0, ...)

最后一行(memset)是否合法?向用户缓冲区写入数据有效吗?该缓冲区可能被DMA用于将数据传输到设备。

2个回答

2

这是合法的。这里没有发生“回环” - 如果您使用动态分配的数组,您应该怎么做呢?在write()之后释放它吗?你不能吗? - 好吧,答案是write()函数(和系统调用)在返回后不会修改或访问用户缓冲区 - 如果无法立即写入,则会复制数据。您不必担心实现细节(毕竟这就是C标准库的目的...)


1
write() 不是 C 标准库的一部分,它是一个更低级别的 Unix 系统调用。 - Barmar
@user1868481 我认为没有任何矛盾 - Barmar的回答也表明,当“写入”时,您的数据已经被写入。 - user529758
但是Barmar建议除了O_DIRECT标志外,还要添加O_SYNC标志。这是必要的吗?我需要这个写操作尽可能快。在这个“写”之后,我用新数据填充相同的用户缓冲区,然后再次使用“写”。我只想知道当我只使用O_DIRECT和“写”时会发生什么,并且DMA被激活。我如何知道安全使用用户缓冲区或者在“写”返回后DMA是否正在使用它... - user1868481
@user1868481:我不确定O_DIRECT是否意味着由HDD控制器提供的DMA。我认为它只是绕过了库内部缓冲区的使用。在硬件级别或使用分布式文件系统时仍可能发生缓存。为确保后者也已被刷新,应使用O_SYNC,以便数据被保证已经被物理保存 - alk
@user1868481,你知道它是安全的,因为它保证是安全的。无论你传递给open()的标志如何,write()都不会在内核中留下一个指向你的用户空间缓冲区的指针,以后尝试异步访问它。当write()返回时,内核不会在任何情况下尝试访问你的用户空间缓冲区。你可以随心所欲地使用它。 - nos
显示剩余3条评论

1

在使用O_DIRECT时,结合使用O_SYNC标志。这样,当write()返回时,您可以确信数据已被写入。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接