Commit a2d9768e authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 4324420a
......@@ -1055,6 +1055,7 @@ pair<Mapping, error> _FileH::mmap(int64_t blk_start, int64_t blk_len, VMA *vma)
mmap->mem_start = mem_start;
mmap->mem_stop = mem_stop;
mmap->vma = vma;
mmap->efaulted = false;
for (auto _ : f._pinned) { // TODO keep f._pinned ↑blk and use binary search
int64_t blk = _.first;
......@@ -1103,6 +1104,22 @@ error _Mapping::__remmapAsEfault() {
etrace("");
error err = mmap_efault_into(mmap.mem_start, mmap.mem_stop - mmap.mem_start);
mmap.efaulted = true;
return E(err);
}
// __remmapBlkAsEfault is similar to __remmapAsEfault, but remmaps memory of only 1 block.
// blk must be in mapped range.
error _Mapping::__remmapBlkAsEfault(int64_t blk) {
_Mapping& mmap = *this;
FileH f = mmap.fileh;
xerr::Contextf E("%s: remmapblk #%ld as efault", v(mmap), blk);
etrace("");
ASSERT(mmap.blk_start <= blk && blk < mmap.blk_stop());
uint8_t *blkmem = mmap.mem_start + (blk - mmap.blk_start)*f->blksize;
error err = mmap_efault_into(blkmem, 1*f->blksize);
return E(err);
}
......@@ -1158,11 +1175,12 @@ error _Mapping::unmap() {
// at=TidHead means unpin to head/ .
// NOTE this does not check whether virtmem already mapped blk as RW.
//
// _remmapblk must not be called after Mapping is switched to efault.
//
// The following locks must be held by caller:
// - f.wconn.atMu
// - f._mmapMu
error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
// XXX must not be called after Mapping is switched to efault?
_Mapping *mmap = this;
FileH f = mmap->fileh;
......@@ -1170,9 +1188,12 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
etrace("");
ASSERT(mmap->blk_start <= blk && blk < mmap->blk_stop());
error err;
// a mmapping is efaulted only for closed files, i.e. fileh is removed from wconn._filehTab
// -> pinner should not see the fileh and so shuold not see this mapping.
ASSERT(!mmap->efaulted);
uint8_t *blkmem = mmap->mem_start + (blk - mmap->blk_start)*f->blksize;
error err;
os::File fsfile;
bool fclose = false;
if (at == TidHead) {
......@@ -1218,11 +1239,13 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
// remmap_blk remmaps file[blk] in its place again.
//
// Virtmem calls Mapping.remmap_blk under virtmem lock to remmap a block after
// RW dirty page was e.g. discarded.
// RW dirty page was e.g. discarded or committed.
error _Mapping::remmap_blk(int64_t blk) {
_Mapping& mmap = *this;
FileH f = mmap.fileh;
error err;
// NOTE virtmem lock is held by virtmem caller
f->wconn->_atMu.RLock();
f->_mmapMu.lock();
......@@ -1234,7 +1257,12 @@ error _Mapping::remmap_blk(int64_t blk) {
if (!(mmap.blk_start <= blk && blk < mmap.blk_stop()))
panic("remmap_blk: blk out of Mapping range");
// XXX do nothing after mapping is switched to efault? (i.e. f is closed/down)
// it should not happen, but if, for a efaulted mapping, virtmem asks us to
// remmap base-layer blk memory in its place again, we reinject efault into it.
if (mmap.efaulted) {
log::Warnf("%s: remmapblk called for already-efaulted mapping", v(mmap));
return mmap.__remmapBlkAsEfault(blk); // TODO recheck errctx
}
// blkrev = rev | @head
zodb::Tid blkrev; bool ok;
......@@ -1242,7 +1270,7 @@ error _Mapping::remmap_blk(int64_t blk) {
if (!ok)
blkrev = TidHead;
error err = mmap._remmapblk(blk, blkrev);
err = mmap._remmapblk(blk, blkrev);
if (err != nil)
return err; // errctx is good in _remmapblk
......
......@@ -282,6 +282,7 @@ struct _Mapping : object {
uint8_t *mem_start; // mmapped memory [mem_start, mem_stop)
uint8_t *mem_stop;
VMA *vma; // mmapped under this virtmem VMA | nil if created standalone from virtmem
bool efaulted; // y after mapping was switched to be invalid (gives SIGSEGV on access)
int64_t blk_stop() const {
ASSERT((mem_stop - mem_start) % fileh->blksize == 0);
......@@ -294,6 +295,7 @@ struct _Mapping : object {
void _assertVMAOk();
error _remmapblk(int64_t blk, zodb::Tid at);
error __remmapAsEfault();
error __remmapBlkAsEfault(int64_t blk);
// don't new - create via FileH.mmap
private:
......
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