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) ...@@ -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_start = mem_start;
mmap->mem_stop = mem_stop; mmap->mem_stop = mem_stop;
mmap->vma = vma; mmap->vma = vma;
mmap->efaulted = false;
for (auto _ : f._pinned) { // TODO keep f._pinned ↑blk and use binary search for (auto _ : f._pinned) { // TODO keep f._pinned ↑blk and use binary search
int64_t blk = _.first; int64_t blk = _.first;
...@@ -1103,6 +1104,22 @@ error _Mapping::__remmapAsEfault() { ...@@ -1103,6 +1104,22 @@ error _Mapping::__remmapAsEfault() {
etrace(""); etrace("");
error err = mmap_efault_into(mmap.mem_start, mmap.mem_stop - mmap.mem_start); 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); return E(err);
} }
...@@ -1158,11 +1175,12 @@ error _Mapping::unmap() { ...@@ -1158,11 +1175,12 @@ error _Mapping::unmap() {
// at=TidHead means unpin to head/ . // at=TidHead means unpin to head/ .
// NOTE this does not check whether virtmem already mapped blk as RW. // 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: // The following locks must be held by caller:
// - f.wconn.atMu // - f.wconn.atMu
// - f._mmapMu // - f._mmapMu
error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) { error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
// XXX must not be called after Mapping is switched to efault?
_Mapping *mmap = this; _Mapping *mmap = this;
FileH f = mmap->fileh; FileH f = mmap->fileh;
...@@ -1170,9 +1188,12 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) { ...@@ -1170,9 +1188,12 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
etrace(""); etrace("");
ASSERT(mmap->blk_start <= blk && blk < mmap->blk_stop()); 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; uint8_t *blkmem = mmap->mem_start + (blk - mmap->blk_start)*f->blksize;
error err;
os::File fsfile; os::File fsfile;
bool fclose = false; bool fclose = false;
if (at == TidHead) { if (at == TidHead) {
...@@ -1218,11 +1239,13 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) { ...@@ -1218,11 +1239,13 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
// remmap_blk remmaps file[blk] in its place again. // remmap_blk remmaps file[blk] in its place again.
// //
// Virtmem calls Mapping.remmap_blk under virtmem lock to remmap a block after // 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) { error _Mapping::remmap_blk(int64_t blk) {
_Mapping& mmap = *this; _Mapping& mmap = *this;
FileH f = mmap.fileh; FileH f = mmap.fileh;
error err;
// NOTE virtmem lock is held by virtmem caller // NOTE virtmem lock is held by virtmem caller
f->wconn->_atMu.RLock(); f->wconn->_atMu.RLock();
f->_mmapMu.lock(); f->_mmapMu.lock();
...@@ -1234,7 +1257,12 @@ error _Mapping::remmap_blk(int64_t blk) { ...@@ -1234,7 +1257,12 @@ error _Mapping::remmap_blk(int64_t blk) {
if (!(mmap.blk_start <= blk && blk < mmap.blk_stop())) if (!(mmap.blk_start <= blk && blk < mmap.blk_stop()))
panic("remmap_blk: blk out of Mapping range"); 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 // blkrev = rev | @head
zodb::Tid blkrev; bool ok; zodb::Tid blkrev; bool ok;
...@@ -1242,7 +1270,7 @@ error _Mapping::remmap_blk(int64_t blk) { ...@@ -1242,7 +1270,7 @@ error _Mapping::remmap_blk(int64_t blk) {
if (!ok) if (!ok)
blkrev = TidHead; blkrev = TidHead;
error err = mmap._remmapblk(blk, blkrev); err = mmap._remmapblk(blk, blkrev);
if (err != nil) if (err != nil)
return err; // errctx is good in _remmapblk return err; // errctx is good in _remmapblk
......
...@@ -282,6 +282,7 @@ struct _Mapping : object { ...@@ -282,6 +282,7 @@ struct _Mapping : object {
uint8_t *mem_start; // mmapped memory [mem_start, mem_stop) uint8_t *mem_start; // mmapped memory [mem_start, mem_stop)
uint8_t *mem_stop; uint8_t *mem_stop;
VMA *vma; // mmapped under this virtmem VMA | nil if created standalone from virtmem 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 { int64_t blk_stop() const {
ASSERT((mem_stop - mem_start) % fileh->blksize == 0); ASSERT((mem_stop - mem_start) % fileh->blksize == 0);
...@@ -294,6 +295,7 @@ struct _Mapping : object { ...@@ -294,6 +295,7 @@ struct _Mapping : object {
void _assertVMAOk(); void _assertVMAOk();
error _remmapblk(int64_t blk, zodb::Tid at); error _remmapblk(int64_t blk, zodb::Tid at);
error __remmapAsEfault(); error __remmapAsEfault();
error __remmapBlkAsEfault(int64_t blk);
// don't new - create via FileH.mmap // don't new - create via FileH.mmap
private: 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