Commit a0323d05 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 25c978bc
......@@ -76,7 +76,7 @@ struct bigfile_ops {
int (*storeblk) (BigFile *file, blk_t blk, const void *buf);
// - mmap_setup_read(vma, file[blk +blklen)) setup initial read-only mmap to serve vma
// - mmap_setup_read(vma, file[blk +blklen)) -> addr setup initial read-only mmap to serve vma
// - remmap_blk_read(vma, file[blk]) remmap blk into vma again, after e.g.
// RW dirty page was discarded
// - munmap(vma) before VMA is unmapped
......@@ -106,7 +106,7 @@ struct bigfile_ops {
* XXX mmap_read -> !loadblk ?
* NOTE blk and blklen are in blocks, not pages.
*
* @addr NULL - mmap at anywhere, !NULL - mmap exactly at addr.
* @addr NULL - mmap at anywhere, !NULL - mmap exactly at addr. XXX
* @return !NULL - mapped there, NULL - error.
*/
void* (*mmap_setup_read) (VMA *vma, BigFile *file, blk_t blk, size_t blklen);
......
......@@ -143,13 +143,29 @@ static error _pathError(const char *op, const string &path, int syserr) {
// mm::
namespace mm {
// map memory-maps f.fd[offset +size) somewhere into memory.
// prot is PROT_* from mmap(2).
// flags is MAP_* from mmap(2); MAP_FIXED must not be used.
tuple<uint8_t*, error> map(int prot, int flags, os::File f, off_t offset, size_t size) {
void *addr;
if (flags & MAP_FIXED)
panic("MAP_FIXED not allowed for map - use map_into");
addr = ::mmap(NULL, size, prot, flags, f->fd(), offset);
if (addr == MAP_FAILED)
return make_tuple(nil, os::_pathError("mmap", f->name(), errno));
return make_tuple((uint8_t*)addr, nil);
}
// map_into memory-maps f.fd[offset +size) into [addr +size).
// prot is PROT_* from mmap(2).
// flags is MAP_* from mmap(2); MAP_FIXED is added automatically.
error map_into(void *addr, size_t size, int prot, int flags, const os::File f, off_t offset) {
error map_into(void *addr, size_t size, int prot, int flags, os::File f, off_t offset) {
void *addr2;
addr2 = mmap(addr, size, prot, MAP_FIXED | flags, f->fd(), offset);
addr2 = ::mmap(addr, size, prot, MAP_FIXED | flags, f->fd(), offset);
if (addr2 == MAP_FAILED)
return os::_pathError("mmap", f->name(), errno);
if (addr2 != addr)
......
......@@ -120,7 +120,8 @@ tuple<File, error> open(const string &path, int flags = O_RDONLY,
// mm::
namespace mm {
error map_into(void *addr, size_t, int prot, int flags, const os::File f, off_t offset);
tuple<uint8_t*, error> map(int prot, int flags, os::File f, off_t offset, size_t size);
error map_into(void *addr, size_t size, int prot, int flags, os::File f, off_t offset);
// XXX unmap
} // mm::
......
......@@ -21,6 +21,8 @@
//
// XXX provides isolated view.
// XXX wcfs_virtmem organization.
#include "wcfs_misc.h"
#include "wcfs.h"
#include "wcfs_watchlink.h"
......@@ -43,12 +45,14 @@
using std::min;
using std::max;
using std::vector;
static string h(uint64_t v); // v -> 016x hex representation
#define h_(v) (h(v).c_str())
static error mmap_zero_into_ro(void *addr, size_t size);
static error mmap_into_ro(void *addr, size_t size, const os::File &f, off_t offset);
static tuple<uint8_t*, error> mmap_ro(os::File f, off_t offset, size_t size);
static error mmap_into_ro(void *addr, size_t size, os::File f, off_t offset);
// _File represent isolated file view under Conn.
//
......@@ -254,6 +258,7 @@ void _Conn::_pin1(PinReq *req) {
_Mapping* _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t blk_len) {
_Conn& wconn = *this;
// XXX err ctx
// XXX (blk_start + blk_len) * blk_size overflow
error err;
if (blk_start < 0)
......@@ -301,36 +306,47 @@ _Mapping* _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t blk_len) {
if (ack != "ok") {
// XXX unregister f from _filetab
// XXX vvv -> errctx?
/*return XXX*/ fmt::errorf("@%s: mmap f<%s>[%d +%d): %s", h_(wconn.at), h_(foid), blk_start, blk_len, ack.c_str());
/*return XXX*/ fmt::errorf("@%s: mmap f<%s>[%zd +%zd): %s", h_(wconn.at), h_(foid), blk_start, blk_len, ack.c_str());
panic("TODO ack != ok"); // XXX ^^^
}
}
// XXX relock wconn -> f ?
// XXX reenable
return nil;
#if 0
// create memory with head/f mapping and applied pins
// mmap-in zeros after f.size (else access to memory after file.size will raise SIGBUS)
start = blk_start*f.blksize
mem = mm.map_ro(f.headf.fileno(), start, blk_len*f.blksize)
zmemtail = mem[max(f.headfsize, start) - start:]
if len(zmemtail) != 0:
mm.map_zero_into_ro(zmemtail)
mmap = _Mapping()
mmap.file = f
mmap.blk_start = blk_start
mmap.mem = mem
for blk, rev in f.pinned.items(): // XXX keep f.pinned ↑blk and use binary search?
if not (blk_start <= blk < blk_stop):
continue // blk out of this mapping
mmap._remmapblk(blk, rev)
f.mmaps.append(mmap) // XXX keep f.mmaps ↑blk_start
int64_t start = blk_start*f->blksize;
uint8_t *mem_start, *mem_stop;
tie(mem_start, err) = mmap_ro(f->headf, start, blk_len*f->blksize);
if (err != nil)
panic("TODO"); // XXX
mem_stop = mem_start + blk_len*f->blksize;
int64_t stop = blk_stop*f->blksize;
if (stop > f->headfsize) {
uint8_t *zmem_start = mem_start + (max(f->headfsize/*XXX -1 ?*/, start) - start);
err = mmap_zero_into_ro(zmem_start, mem_stop - zmem_start);
if (err != nil)
panic("TODO"); // XXX
}
_Mapping* mmap = new _Mapping();
mmap->file = f;
mmap->blk_start = blk_start;
mmap->mem_start = mem_start;
mmap->mem_stop = mem_stop;
for (auto _ : f->pinned) { // XXX keep f.pinned ↑blk and use binary search?
int64_t blk = _.first;
zodb::Tid rev = _.second;
if (!(blk_start <= blk && blk < blk_stop))
continue; // blk out of this mapping
mmap->_remmapblk(blk, rev); // XXX err?
}
f->mmaps.push_back(mmap); // XXX keep f.mmaps ↑blk_start
return mmap;
#endif
}
// resync resyncs connection and its mappings onto different database view.
......@@ -477,7 +493,7 @@ static string h(uint64_t v) {
return fmt::sprintf("%016lx", v);
}
// mmap_zero_ro mmaps read-only zeros into [addr +size) so that region as all zeros.
// mmap_zero_into_ro mmaps read-only zeros into [addr +size) so that region as all zeros.
// created mapping, even after it is accessed, does not consume memory.
static error _mmap_zero_into_ro(void *addr, size_t size);
static error mmap_zero_into_ro(void *addr, size_t size) {
......@@ -503,9 +519,15 @@ static error _mmap_zero_into_ro(void *addr, size_t size) {
return nil;
}
// mmap_ro mmaps read-only fd[offset +size).
// The mapping is created with MAP_SHARED.
static tuple<uint8_t*, error> mmap_ro(os::File f, off_t offset, size_t size) {
return mm::map(PROT_READ, MAP_SHARED, f, offset, size);
}
// mmap_into_ro mmaps read-only fd[offset +size) into [addr +size).
// The mapping is created with MAP_SHARED.
static error mmap_into_ro(void *addr, size_t size, const os::File &f, off_t offset) {
static error mmap_into_ro(void *addr, size_t size, os::File f, off_t offset) {
return mm::map_into(addr, size, PROT_READ, MAP_SHARED, f, offset);
}
......
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