用于直接 IO 的 mmap:地址错误?

发布于 2024-09-15 07:09:26 字数 1187 浏览 10 评论 0原文

我用匿名 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无力看清 2024-09-22 07:09:26

PROT_NONE 页面可能不
已访问。

你不应该至少将 PROT_READ 作为 mmap 的 3. 参数吗?为了在这种情况下有用,您可能需要 PROT_READ|PROT_WRITE

PROT_NONE Pages may not be
accessed.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文