Frage

Der folgende C-Code zeigt ein Problem, das ich unter Linux 2.6.30.5-43.fc11.x86_64 sehe:

#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;
}

Dies schlägt immer mit Remap_File_Pages () zurück, die -1 und errno auf Einval zurückgegeben werden. Wenn ich mir die Kernelquelle anschaue, kann ich alle Bedingungen in Remap_File_Pages () sehen, in denen sie möglicherweise fehlschlagen, aber keiner von ihnen scheint für mein Beispiel zu gelten. Was ist los?

War es hilfreich?

Lösung

Es wird durch die geöffnete Datei verursacht O_RDONLY. Wenn Sie den offenen Modus an ändern, um O_RDWR, es funktioniert (auch wenn das mmap() Gibt immer noch gerecht an PROT_READ).

Dieser Code in do_mmap_pgoff ist die Grundursache - sie markiert nur die VMA als VM_SHARED Wenn die Datei zum Schreiben geöffnet wurde:

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

Also in remap_file_pages(), Sie scheitern beim ersten Scheck:

if (!vma || !(vma->vm_flags & VM_SHARED))
    goto out;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top