2010-02-08 3 views
4

Следующий код C иллюстрирует проблему, я вижу на Linux 2.6.30.5-43.fc11.x86_64:Почему remap_file_pages() не работает в этом примере?

#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/mman.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

int main() { 
    char buf[1024]; 
    void *base; 
    int fd; 
    size_t pagesz = sysconf(_SC_PAGE_SIZE); 

    fd = open("<some file, at least 4*pagesz in length>", O_RDONLY); 
    if (fd < 0) { 
     perror("open"); 
     return 1; 
    } 

    base = mmap(0, 4*pagesz, PROT_READ, MAP_SHARED, fd, 0); 
    if (base < 0) { 
     perror("mmap"); 
     close(fd); 
     return 1; 
    } 

    memcpy(buf, (char*)base + 2*pagesz, 1024); 

    if (remap_file_pages(base, pagesz, 0, 2, 0) < 0) { 
     perror("remap_file_pages"); 
     munmap(base, 4*pagesz); 
     close(fd); 
     return 1; 
    } 

    printf("%d\n", memcmp(buf, base, 1024)); 

    munmap(base, 4*pagesz); 
    close(fd); 
    return 0; 
} 

Это всегда терпит неудачу с remap_file_pages() возвращается -1 и ERRNO установлен в EINVAL. Если посмотреть на источник ядра, я могу увидеть все условия в файле remap_file_pages(), где он может выйти из строя, но ни один из них, похоже, не применим к моему примеру. Что происходит?

ответ

5

Это связано с тем, что файл открыт O_RDONLY. Если вы измените открытый режим на O_RDWR, он работает (даже если mmap() все еще указывает только PROT_READ).

Этот код в do_mmap_pgoff является первопричиной - отмечает он только VMA как VM_SHARED, если файл был открыт для записи:

vm_flags |= VM_SHARED | VM_MAYSHARE; 
if (!(file->f_mode & FMODE_WRITE)) 
    vm_flags &= ~(VM_MAYWRITE | VM_SHARED); 

Так remap_file_pages(), вы не на первой проверки:

if (!vma || !(vma->vm_flags & VM_SHARED)) 
    goto out; 
+0

Это прекрасно работает, спасибо. –

+0

Есть ли у вас объяснения, почему требуется «O_RDWR»? Кажется странным для меня ... –

+0

@R .: Кажется, это результат тонкого взаимодействия, которое я не совсем уверен в этом. – caf

Смежные вопросы