写入错误:使用O_DIRECT打开文件时,参数无效 [英] Write error: Invalid argument, when file is opened with O_DIRECT
问题描述
用O_DIRECT
标志写入文件对我来说非常重要.
it is very important to me to write to a file with the O_DIRECT
flag.
这是我打开文件的方式:
This is how I open the file:
//Open the file
int fd;
if((fd = open(inFilepath, O_WRONLY | O_CREAT |O_SYNC |O_DIRECT,S_IRUSR|S_IWUSR))<0) {
//Error handling
return;
}
我知道O_DIRECT的对齐限制.这就是为什么我用calloc初始化缓冲区的原因:
I know about O_DIRECT's alignment restrictions. This is why I initialize my buffer with calloc:
char *buff = (char *) calloc((size_t) 1,sizeof(char));
if(write(fd,buff,(size_t)1)<1) {
//Error logging
free(buff);
return -1;
}
我得到了write: Invalid argument
错误.
我什至尝试使用更极端的措施,例如memalign和posix_memalign,但它们存在问题(memalign卡住了,ARM处理器缺少posix_memalign).
And I get the write: Invalid argument
error.
I even tried to use more extreme measures such as memalign and posix_memalign, but had issues with them (memalign got stuck, and posix_memalign is missing for the ARM processor).
当我注释掉O_DIRECT
标志时,一切都会正常进行(但是I/O不是直接的,这正是我所需要的).
When I comment out the O_DIRECT
flag, everything works as it should (but I/O is not direct, which is what I need).
任何人都知道为什么会这样吗?如果O_DIRECT
不是在Android中实现的,则它应该在open()
而不是在write()
处失败;所以我一定做错了!
Anyone has any insight as to why this is happening? If O_DIRECT
was not implemented in Android, then it should've failed at open()
, not at write()
; so I must be doing something wrong!
谢谢 -LD
推荐答案
我已解决(根据您的指导)-并希望发布我的解决方案,以防将来有人遇到类似问题.
I solved it (with your guidance)- and wanted to post my solution in case anyone in the future has similar problems.
诀窍在于,使用O_DIRECT
标志,您需要将内存地址和缓冲区都与文件系统的块大小对齐(或者至少对我来说块大小有效;扇区无效).
The trick was that with the O_DIRECT
flag you need to align both the memory address and your buffer to the filesystem's block size (or at least, block size worked for me; sector didn't).
struct stat fstat;
stat(filepath, &fstat);
int blksize = (int)fstat.st_blksize;
int align = blksize-1;
const char *buff = (char *) malloc((int)blksize+align);
buff = (char *)(((uintptr_t)buff+align)&~((uintptr_t)align));
if(write(fd,buff,(size_t)blksize)<1) {
//Error handling
free((char *)buff);
return -1;
}
我做了两件事:
- 使用
stat()
并访问st_blksize
属性找到了托管我的文件块大小的文件系统. - 分配的
align
个字节超出了我的需要.然后,我将那些额外的align
字节添加到指针地址,以便将这些位屏蔽为较低的块大小对齐方式,不会给我分配的内存少于我想要的.然后,当然,您可以将这些位与掩码(通过翻转align
的位,即blksize
-1的位而创建)进行对,并确保缓冲区是blksize
对齐的.
- Found the filesystem hosting my file's block size using
stat()
and accessing thest_blksize
attribute. - Allocated
align
more bytes than I need. I then added those extraalign
bytes to the pointer address so that masking off the bits to the lower block size alignment wouldn't leave me with less memory allocated than I wanted. Then of course you AND the bits with the mask (created by flipping the bits ofalign
which isblksize
-1), and voila- your buffer isblksize
-aligned.
还请注意,您写的数量还必须与块大小保持一致(至少在我的情况下如此).
Also note that the amount you write also has to be aligned to block size (at least in my case).
-LD
这篇关于写入错误:使用O_DIRECT打开文件时,参数无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!