Commit 1bbf1c49 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 326c880b
......@@ -173,6 +173,7 @@ def test_wcfs_client():
# XXX wconn.open() after wconn.close() -> error
# XXX wconn.resync() after wconn.close() -> error
# XXX all fileh / mappings become invalid after wconn.close
......
......@@ -198,6 +198,7 @@ using std::vector;
namespace wcfs {
static error mmap_zero_into_ro(void *addr, size_t size);
static error mmap_efault_into(void *addr, size_t size);
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);
......@@ -412,7 +413,7 @@ error _Conn::__pin1(PinReq *req) {
// So if we take virt_lock right around mmap._remmapblk(), the order of
// locks in pinner would be
//
// wconn.atMu.R, wconn.filehMu.R, f.mu, virt_lock
// wconn.atMu.R, wconn.filehMu.R, fileh.mu, virt_lock
//
// which means there is AB-BA deadlock possibility.
//
......@@ -810,6 +811,8 @@ error _FileH::close() {
_FileH& fileh = *this;
Conn wconn = fileh.wconn;
// XXX virt_lock + explain (refer to __pin1)
wconn->_atMu.RLock();
wconn->_filehMu.Lock();
defer([&]() {
......@@ -1023,6 +1026,8 @@ error _Mapping::unmap() {
// - f.wconn.atMu
// - f._mu XXX not needed? (f._mmaps and f._pinned are not used)
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;
xerr::Contextf E("%s: f<%s>: remmapblk #%ld @%s", v(f->wconn), v(f->foid), blk, v(at));
......@@ -1093,6 +1098,8 @@ 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)
// blkrev = rev | @head
zodb::Tid blkrev; bool ok;
tie(blkrev, ok) = f->_pinned.get_(blk);
......@@ -1125,9 +1132,8 @@ tuple<os::File, error> WCFS::_open(const string &path, int flags) {
// ---- misc ----
// mmap_zero_into_ro mmaps read-only zeros into [addr +size) so that region is all zeros.
// created mapping, even after it is accessed, does not consume memory.
static error mmap_zero_into_ro(void *addr, size_t size) {
// mmap_zero_into serves mmap_zero_into_ro and mmap_efault_into.
static error mmap_zero_into(void *addr, size_t size, int prot) {
xerr::Contextf E("mmap zero");
etrace("");
......@@ -1141,12 +1147,29 @@ static error mmap_zero_into_ro(void *addr, size_t size) {
defer([&]() {
z->close();
});
err = mm::map_into(addr, size, PROT_READ, MAP_SHARED | MAP_NORESERVE, z, 0);
err = mm::map_into(addr, size, prot, MAP_SHARED | MAP_NORESERVE, z, 0);
if (err != nil)
return E(err);
return nil;
}
// mmap_zero_into_ro mmaps read-only zeros into [addr +size) so that region is all zeros.
// created mapping, even after it is accessed, does not consume memory.
static error mmap_zero_into_ro(void *addr, size_t size) {
return mmap_zero_into(addr, size, PROT_READ);
}
// mmap_efault_into changes [addr +size) region to generate SIGSEGV on read/write access.
// Any previous mapping residing in that virtual address range is released.
static error mmap_efault_into(void *addr, size_t size) {
xerr::Contextf E("mmap efault");
etrace("");
// mmaping /dev/zero with PROT_NONE gives what we need.
return E(mmap_zero_into(addr, size, PROT_NONE));
}
// 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) {
......
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