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

.

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