Commit 199f3d79 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 6ada59d3
...@@ -201,6 +201,7 @@ const char *__tsan_default_options() ...@@ -201,6 +201,7 @@ const char *__tsan_default_options()
/* whether appropriate page of vma is mapped */ /* whether appropriate page of vma is mapped */
// XXX BUG on out-of-bounds
int M(VMA *vma, pgoff_t idx) { return bitmap_test_bit(vma->page_ismappedv, idx); } int M(VMA *vma, pgoff_t idx) { return bitmap_test_bit(vma->page_ismappedv, idx); }
...@@ -1112,6 +1113,90 @@ void test_pagefault_savestate() ...@@ -1112,6 +1113,90 @@ void test_pagefault_savestate()
#undef CHECK_NOPAGE #undef CHECK_NOPAGE
} }
/* ---------------------------------------- */
/* test access to file mappings with file having .mmap* instead of .loadblk
*
* mmapbase is virtmem mode used with wcfs: RAM pages are used only for dirtied
* data and everything else comes as read-only mmap from wcfs file.
*/
/* file that mmaps blkdata */ // XXX
struct BigFileMMap {
BigFile;
int fd; /* fd of file to mmap */
};
typedef struct BigFileMMap BigFileMMap;
void *mmapfile_mmap_setup_read(BigFile *file, blk_t blk, size_t blklen, VMA *vma) {
BigFileMMap *f = upcast(BigFileMMap*, file);
void *addr;
addr = mmap(NULL, blklen*f->blksize, PROT_READ, MAP_SHARED, f->fd, blk*f->blksize);
if (addr == MAP_FAILED)
addr = NULL;
return addr;
}
void mmapfile_release(BigFile *file) {
BigFileMMap *f = upcast(BigFileMMap*, file);
int err;
err = close(f->fd);
BUG_ON(err);
}
static const struct bigfile_ops mmapfile_ops = {
.loadblk = NULL,
// .storeblk = mmapfile_storeblk,
.mmap_setup_read = mmapfile_mmap_setup_read,
.release = mmapfile_release,
};
void test_file_access_mmapbase(void)
{
RAM *ram;
BigFileH fh_struct, *fh = &fh_struct;
VMA vma_struct, *vma = &vma_struct;
size_t PS;
int fd, err;
diag("Testing file access (mmap base)");
ram = ram_new(NULL, NULL);
ok1(ram);
PS = ram->pagesize;
/* ensure we are starting from new ram */
ok1(list_empty(&ram->lru_list));
/* setup mmaped id file */
char path[] = "/tmp/bigfile_mmap.XXXXXX";
fd = mkstemp(path);
ok1(fd != -1);
err = unlink(path);
ok1(!err);
BigFileMMap fileid = {
.blksize = ram->pagesize, /* artificially blksize = pagesize */
.file_ops = &mmapfile_ops,
.fd = fd,
};
err = fileh_open(fh, &fileid, ram);
ok1(!err);
/* implicitly use fileh=fh */
#define CHECK_PAGE(page, pgoffset, pgstate, pgrefcnt) \
__CHECK_PAGE(page, fh, pgoffset, pgstate, pgrefcnt)
#define CHECK_NOPAGE(pgoffset) __CHECK_NOPAGE(fh, pgoffset)
err = fileh_mmap(vma, fh, 100, 4);
ok1(!err);
}
// TODO test for loadblk that returns -1 // TODO test for loadblk that returns -1
...@@ -1120,9 +1205,12 @@ int main() ...@@ -1120,9 +1205,12 @@ int main()
{ {
tap_fail_callback = abort; // XXX to catch failure immediately tap_fail_callback = abort; // XXX to catch failure immediately
if (0) {
test_vmamap(); test_vmamap();
test_file_access_synthetic(); test_file_access_synthetic();
test_file_access_pagefault(); test_file_access_pagefault();
test_pagefault_savestate(); test_pagefault_savestate();
}
test_file_access_mmapbase();
return 0; return 0;
} }
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
#include <stddef.h> #include <stddef.h>
#include <wendelin/bigfile/types.h> #include <wendelin/bigfile/types.h>
// XXX move everything into virtmem.h ?
#include <wendelin/bigfile/virtmem.h> // for VMA
/* BigFile base class /* BigFile base class
* *
...@@ -69,7 +72,9 @@ struct bigfile_ops { ...@@ -69,7 +72,9 @@ struct bigfile_ops {
int (*storeblk) (BigFile *file, blk_t blk, const void *buf); int (*storeblk) (BigFile *file, blk_t blk, const void *buf);
/* mmap_read is called to mmap read-only file[blk +blklen) into @addr. /* mmap_setup_read is called to setup new read-only mapping of file[blk +blklen).
*
* The mapping will be used as the base read-only layer for vma.
* *
* XXX mmap_read -> !loadblk ? * XXX mmap_read -> !loadblk ?
* NOTE blk and blklen are in blocks, not pages. * NOTE blk and blklen are in blocks, not pages.
...@@ -77,9 +82,10 @@ struct bigfile_ops { ...@@ -77,9 +82,10 @@ struct bigfile_ops {
* @addr NULL - mmap at anywhere, !NULL - mmap exactly at addr. * @addr NULL - mmap at anywhere, !NULL - mmap exactly at addr.
* @return !NULL - mapped there, NULL - error. * @return !NULL - mapped there, NULL - error.
*/ */
void* (*mmap_read) (BigFile *file, void *addr, blk_t blk, size_t blklen); // void* (*mmap_read) (BigFile *file, void *addr, blk_t blk, size_t blklen);
void* (*mmap_setup_read) (BigFile *file, blk_t blk, size_t blklen, VMA *vma);
// - mmap_read(vma) setup initial read-only mmap // - mmap_setup_read(vma) setup initial read-only mmap
// - mresync(vma, was_dirtyv) forget RW dirty pages -> mmap them back read-only to file data // - mresync(vma, was_dirtyv) forget RW dirty pages -> mmap them back read-only to file data
// - munmap(vma) before VMA is unmapped // - munmap(vma) before VMA is unmapped
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define _WENDELIN_TESTING_UTILS_H_ #define _WENDELIN_TESTING_UTILS_H_
/* Wendelin.bigfile | various testing utilities /* Wendelin.bigfile | various testing utilities
* Copyright (C) 2014-2015 Nexedi SA and Contributors. * Copyright (C) 2014-2019 Nexedi SA and Contributors.
* Kirill Smelkov <kirr@nexedi.com> * Kirill Smelkov <kirr@nexedi.com>
* *
* This program is free software: you can Use, Study, Modify and Redistribute * This program is free software: you can Use, Study, Modify and Redistribute
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <wendelin/bigfile/ram.h> #include <wendelin/bigfile/ram.h>
/* access to vma memory as byte[] and blk_t[] */ /* access to vma memory as byte[] and blk_t[] */
// XXX BUG on out-of-bound access
#define b(vma, idx) ( ((volatile uint8_t *)vma->addr_start) [ idx ] ) #define b(vma, idx) ( ((volatile uint8_t *)vma->addr_start) [ idx ] )
#define B(vma, idx) ( ((volatile blk_t *)vma->addr_start) [ idx ] ) #define B(vma, idx) ( ((volatile blk_t *)vma->addr_start) [ idx ] )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment