繁体   English   中英

O_DIRECT标志无效

[英]O_DIRECT flag not working

董事会简介:

我正在制作一块有ST40芯片的主板,主要用于捕获DVB流并在电视上显示。 该板在Linux OS上运行。

问题描述:

我试图使用O_DIRECT标志从USB上的大文件(大约2 GB)读取数据。 以下是相关的代码段:

char subblk[BLKSIZE];
open (filename2,O_CREAT|O_WRONLY|O_DIRECT,S_IRWXU|S_IRWXG|S_IRWXO);
read (fp,subblk,BLKSIZE);

它说读取失败,错误号为22 - "EINVAL 22 /* Invalid argument"

为了澄清这是一个编程问题还是一些与架构有关的问题,我在我的桌面系统上运行了相同的代码,它工作得非常好,我能够打印我刚读过的字符。 我的ST40主板出现故障的原因是什么?

您应该按文件系统块边界对齐缓冲区。 要实现这一点,你不应该在堆栈上使用缓冲区(如在你的例子中),也不应该调用malloc(BLKSIZE) ,但你应该使用memalign ()。 所以你的代码将是:

/* make sure BLKSIZE is defined as 512 */
char *subblk = memalign(BLKSIZE, BLKSIZE);
open (filename2,O_CREAT|O_WRONLY|O_DIRECT,S_IRWXU|S_IRWXG|S_IRWXO);
read (fp,subblk,BLKSIZE);

为什么您的代码在桌面上工作可能是意外对齐不同的文件系统类型(没有对齐要求)。

引用手册页:

O_DIRECT标志可能会对用户空间缓冲区的长度和地址以及I / O的文件偏移量施加对齐限制。 在Linux中,对齐限制因文件系统和内核版本而异,可能完全不存在。 但是,当前没有与文件系统无关的接口,应用程序可以发现给定文件或文件系统的这些限制。 某些文件系统提供了自己的接口,例如xfsctl(3)中的XFS_IOC_DIOINFO操作。

在Linux 2.4下,传输大小,用户缓冲区和文件偏移的对齐必须都是文件系统逻辑块大小的倍数。 在Linux 2.6下,对齐到512字节边界就足够了。

你的subblk块是否良好对齐? 两个系统是否具有相同的文件系统和/或内核版本?

O_DIRECT标志在内部使用DMA,在我的内核中,DMA未启用。 这就是为什么它在我的桌面电脑上工作但在电路板上没有功能的基本原因。他们有不同的内核,其中一个启用了DMA,另一个没有启用DMA。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM