Mmap для прямого ввода-вывода: плохой адрес? - PullRequest
1 голос
/ 23 августа 2010

Я выделил немного памяти анонимному 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);

тогда я пишу ему, используя fd, открытый с 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");
}

но получен неверный адрес:

allocated buffer: 0x7f096ddff000, 512000
writing to address: 0x7f096ddff000 size: 512000
failed to write: Bad address

Адрес выглядит хорошо для меня.

Если я выделяю буфер в .data и выравниваю по 512, запись работает, поэтому с open () и write () все в порядке, у меня есть все разрешения и т. Д.

Что не так? Существуют ли другие требования для прямого ввода-вывода, кроме 512 выравнивания?

UPDATE:

например, если я изменю 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

1 Ответ

3 голосов
/ 23 августа 2010

PROT_NONE Страницы могут быть недоступны.

Разве вы не должны хотя бы PROT_READ использовать в качестве аргумента 3. для mmap?И чтобы быть полезным в этом случае, вам, вероятно, понадобится PROT_READ | PROT_WRITE

...