2

我想知道在什么情况下直接 I/O 传输会失败?

为此,我有以下三个子查询。根据“理解 Linux 内核”一书。

  1. Linux 提供了一种绕过页面缓存的简单方法:直接 I/O 传输。在每个 I/O 直接传输中,内核对磁盘控制器进行编程,以将数据直接从属于自缓存应用程序的用户模式地址空间的页面传输到/传输。

-- 所以要解释失败,需要检查应用程序是否具有自缓存功能?不确定如何做到这一点。

2.此外,书中说“当自缓存应用程序希望直接访问文件时,它会打开指定 O_DIRECT 标志的文件。在为 open() 系统调用提供服务时,dentry_open() 函数检查是否实现了 direct_IO 方法对于正在打开的文件的地址空间对象,并在相反的情况下返回错误代码”。

——除此之外,还有什么其他原因可以解释直接 I/O 故障?

3.这个命令“dd if=/dev/zero of=myfile bs=1M count=1 oflag=direct”会不会在linux中失败(假设有足够的磁盘空间)?

4

2 回答 2

1

底层文件系统和块设备必须支持O_DIRECT标志。此命令将失败,因为 tmpfs 不支持O_DIRECT.

dd if=/dev/zero of=/dev/shm/test bs=1M count=1 oflag=direct

写入大小必须是底层驱动程序块大小的乘积。此命令将失败,因为 123 不是 512 的乘积:

dd if=/dev/zero of=myfile bs=123 count=1 oflag=direct
于 2012-10-29T06:16:51.503 回答
0

直接 I/O 会继续失败的原因有很多。

因此,要解释失败,需要检查应用程序是否具有自缓存功能?

您不能在外部执行此操作 - 您可以从源代码中推断出这一点,或者观察程序在运行时如何使用资源(我猜是二进制反汇编)。这更多是程序如何工作的属性,而不是“在调用中打开此功能”。认为所有使用O_DIRECT自缓存的程序都是一个危险的假设(从概率上我会说它更有可能,但你不确定)。

  1. 使用有严格的要求,O_DIRECT在 open 的手册页中有提到(参见O_DIRECTNOTES 部分)
  2. 对于现代内核,被操作的区域必须与磁盘块大小对齐,并且其大小必须是磁盘块大小的倍数。未能正确执行此操作甚至可能导致静默回退到缓冲 I/O。
  3. 是的,例如尝试在文件系统(例如tmpfs)上使用它不支持O_DIRECT. 我想如果到磁盘的路径由于某种原因返回故障(例如,与写回发生的情况相比,磁盘正在死并且返回错误要快得多),它也可能会失败。
于 2018-09-05T06:01:23.020 回答