【发布时间】:2018-12-23 10:25:10
【问题描述】:
man 2 read 说:
EINVAL fd 附加到不适合读取的对象;或者 该文件是用 O_DIRECT 标志打开的,并且地址 buf 中指定的值、count 中指定的值或当前文件 偏移量未适当对齐。
Non-direct I/O 没有这样的限制,但为什么直接 I/O 需要对齐呢?
【问题讨论】:
man 2 read 说:
EINVAL fd 附加到不适合读取的对象;或者 该文件是用 O_DIRECT 标志打开的,并且地址 buf 中指定的值、count 中指定的值或当前文件 偏移量未适当对齐。
Non-direct I/O 没有这样的限制,但为什么直接 I/O 需要对齐呢?
【问题讨论】:
(Kernel 2.6+) 这是因为从内核的角度来看,直接 I/O 可以是零拷贝(即不再在内核中进行数据本身的拷贝)并且磁盘具有I/O 的最小可寻址大小称为“逻辑块大小”(通常为 512 字节,但可能为 4096 字节甚至更多)。这个O_DIRECT requirement (must obey logical block size alignments) is actually described in the man page for open()(参见注释下的O_DIRECT 部分)。
在缓冲 I/O 的情况下,内核将数据从用户空间地址复制到它自己的内部页面缓存地址(它遵守所有对齐规则,并在必要时执行 read-modify-write 以确保一切正常对齐),然后告诉设备对/从页面缓存位置执行 I/O。在直接 I/O 情况下,当一切正常时,分配给用户空间程序的内存与交给设备进行 I/O 的内存相同,因此您的程序必须遵守对齐,因为两者之间没有任何东西会解决问题。
【讨论】: