用于直接 IO 的 mmap:地址错误?
我用匿名 mmap 分配了一些内存:
buff->addr = mmap(NULL, length, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS -1, 0);
fprintf(stderr, "allocated buffer: %p, %lu\n", buff->addr, (unsigned long)length);
然后我使用用 O_DIRECT 打开的 fd 写入它:
int fd = open(name, O_CREAT | O_TRUNC | O_WRONLY | O_DIRECT, 00300);
if(fd == -1)
{
perror("failed to open for write");
return;
}
fprintf(stderr, "writing to address: %p size: %lu\n", buff.addr, buff.length);
if(write(fd, buff.addr, buff.length) != size)
{
perror("failed to write");
}
但出现错误地址错误:
allocated buffer: 0x7f096ddff000, 512000
writing to address: 0x7f096ddff000 size: 512000
failed to write: Bad address
该地址对我来说看起来不错。
如果我在 .data 中分配缓冲区并与 512 对齐,则写入有效,因此 open() 和 write() 正常,我拥有所有权限等。出了
什么问题?除了512对齐之外,直接IO还有其他要求吗?
更新:
例如,如果我为此更改 mmap:
char buffer[ 1024000 ];
for(buff->addr = buffer; ((unsigned long)buff->addr % 512) != 0; buff->addr = buff->addr + 1);
它有效:
allocated buffer: 0x500e00, 512000
writing to address: 0x500e00 size: 512000
I allocated some memory with anonymous mmap:
buff->addr = mmap(NULL, length, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS -1, 0);
fprintf(stderr, "allocated buffer: %p, %lu\n", buff->addr, (unsigned long)length);
then I'm writing to it using fd opened with O_DIRECT:
int fd = open(name, O_CREAT | O_TRUNC | O_WRONLY | O_DIRECT, 00300);
if(fd == -1)
{
perror("failed to open for write");
return;
}
fprintf(stderr, "writing to address: %p size: %lu\n", buff.addr, buff.length);
if(write(fd, buff.addr, buff.length) != size)
{
perror("failed to write");
}
but get bad address error:
allocated buffer: 0x7f096ddff000, 512000
writing to address: 0x7f096ddff000 size: 512000
failed to write: Bad address
The address looks good to me.
If I allocate the buffer in .data and align to 512, the write works, so the open() and write() are ok, I have all permissions, etc.
What's wrong? Are there other requirements for direct IO than 512 alignment?
UPDATE:
for example, if I change mmap for this:
char buffer[ 1024000 ];
for(buff->addr = buffer; ((unsigned long)buff->addr % 512) != 0; buff->addr = buff->addr + 1);
it works:
allocated buffer: 0x500e00, 512000
writing to address: 0x500e00 size: 512000
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你不应该至少将 PROT_READ 作为 mmap 的 3. 参数吗?为了在这种情况下有用,您可能需要 PROT_READ|PROT_WRITE
Shouldn't you atleast have PROT_READ as the 3. argument to mmap ? And to be useful in this case, you probably need PROT_READ|PROT_WRITE