Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Kirill Smelkov
wendelin.core
Commits
f5e5d1bc
Commit
f5e5d1bc
authored
Feb 21, 2020
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
ade0ae79
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
124 additions
and
125 deletions
+124
-125
wcfs/client/wcfs.cpp
wcfs/client/wcfs.cpp
+124
-125
No files found.
wcfs/client/wcfs.cpp
View file @
f5e5d1bc
...
...
@@ -511,131 +511,6 @@ error _FileH::close() {
return
E
(
fileh
.
_headf
->
close
());
}
// mmap creates file mapping representing file[blk_start +blk_len) data as of wconn.at database state.
//
// If vma != nil, created mapping is associated with that vma of user-space virtual memory manager:
// virtmem calls FileH::mmap under virtmem lock when virtmem fileh is mmapped into vma.
pair
<
Mapping
,
error
>
_FileH
::
mmap
(
int64_t
blk_start
,
int64_t
blk_len
,
VMA
*
vma
)
{
_FileH
&
f
=
*
this
;
xerr
::
Contextf
E
(
"%s: mmap f<%s> [blk%ld +blk%ld)"
,
v
(
f
.
wconn
),
v
(
f
.
foid
),
blk_start
,
blk_len
);
error
err
;
if
(
blk_start
<
0
)
panic
(
"blk_start < 0"
);
if
(
blk_len
<
0
)
panic
(
"blk_len < 0"
);
int64_t
blk_stop
;
// = blk_start + blk_len
if
(
__builtin_add_overflow
(
blk_start
,
blk_len
,
&
blk_stop
))
panic
(
"blk_start + blk_len overflow int64"
);
int64_t
stop
;
// = blk_stop *f.blksize;
if
(
__builtin_mul_overflow
(
blk_stop
,
f
.
blksize
,
&
stop
))
panic
(
"(blk_start + blk_len)*f.blksize overflow int64"
);
int64_t
start
=
blk_start
*
f
.
blksize
;
// NOTE virtmem lock is held by virtmem caller
// XXX locking
// XXX + wconn.atMu.RLock() ? -> y (e.g. f.headfsize is used)
// f.mu.lock()
// 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)
uint8_t
*
mem_start
,
*
mem_stop
;
tie
(
mem_start
,
err
)
=
mmap_ro
(
f
.
_headf
,
start
,
blk_len
*
f
.
blksize
);
if
(
err
!=
nil
)
return
make_pair
(
nil
,
E
(
err
));
mem_stop
=
mem_start
+
blk_len
*
f
.
blksize
;
bool
retok
=
false
;
defer
([
&
]()
{
if
(
!
retok
)
mm
::
unmap
(
mem_start
,
mem_stop
-
mem_start
);
// ignore error
});
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
)
return
make_pair
(
nil
,
E
(
err
));
}
Mapping
mmap
=
adoptref
(
new
_Mapping
());
mmap
->
fileh
=
newref
(
&
f
);
mmap
->
blk_start
=
blk_start
;
mmap
->
mem_start
=
mem_start
;
mmap
->
mem_stop
=
mem_stop
;
mmap
->
vma
=
vma
;
for
(
auto
_
:
f
.
_pinned
)
{
// TODO 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 ∉ this mapping
err
=
mmap
->
_remmapblk
(
blk
,
rev
);
if
(
err
!=
nil
)
return
make_pair
(
nil
,
E
(
err
));
}
if
(
vma
!=
nil
)
{
if
(
vma
->
mmap_overlay_server
!=
nil
)
panic
(
"vma is already associated with overlay server"
);
if
(
!
(
vma
->
addr_start
==
0
&&
vma
->
addr_stop
==
0
))
panic
(
"vma already covers !nil virtual memory area"
);
mmap
->
incref
();
// vma->mmap_overlay_server is keeping ref to mmap
vma
->
mmap_overlay_server
=
mmap
.
_ptr
();
vma
->
addr_start
=
(
uintptr_t
)
mmap
->
mem_start
;
vma
->
addr_stop
=
(
uintptr_t
)
mmap
->
mem_stop
;
mmap
->
_assertVMAOk
();
// just in case
}
f
.
_mmaps
.
push_back
(
mmap
);
// TODO keep f._mmaps ↑blk_start
retok
=
true
;
return
make_pair
(
mmap
,
nil
);
}
// unmap releases mapping memory from address space.
//
// After call to unmap the mapping must no longer be used.
// The association in between mapping and linked virtmem VMA is reset.
//
// Virtmem calls Mapping.unmap under virtmem lock when VMA is unmapped.
error
_Mapping
::
unmap
()
{
Mapping
mmap
=
newref
(
this
);
// XXX newref for std::remove
FileH
f
=
mmap
->
fileh
;
xerr
::
Contextf
E
(
"%s: f<%s>: unmap"
,
v
(
f
->
wconn
),
v
(
f
->
foid
));
// NOTE virtmem lock is held by virtmem caller
// XXX locking
// wconn.atMu.RLock() + f.mu.lock()
if
(
mmap
->
vma
!=
nil
)
{
mmap
->
_assertVMAOk
();
VMA
*
vma
=
mmap
->
vma
;
vma
->
mmap_overlay_server
=
nil
;
mmap
->
decref
();
// vma->mmap_overlay_server was holding a ref to mmap
vma
->
addr_start
=
0
;
vma
->
addr_stop
=
0
;
mmap
->
vma
=
nil
;
}
error
err
=
mm
::
unmap
(
mmap
->
mem_start
,
mmap
->
mem_stop
-
mmap
->
mem_start
);
mmap
->
mem_start
=
nil
;
mmap
->
mem_stop
=
nil
;
// XXX clear other fields?
// XXX do it first? (to avoid pinner going through f.mmaps and hitting unmapped memory)
//f->_mmaps.remove(mmap);
f
->
_mmaps
.
erase
(
std
::
remove
(
f
->
_mmaps
.
begin
(),
f
->
_mmaps
.
end
(),
mmap
),
f
->
_mmaps
.
end
());
return
E
(
err
);
}
// resync resyncs connection and its file mappings onto different database view.
// XXX place=? -> closer to pinner & connect
error
_Conn
::
resync
(
zodb
::
Tid
at
)
{
...
...
@@ -770,6 +645,130 @@ error _Conn::resync(zodb::Tid at) {
return
nil
;
}
// mmap creates file mapping representing file[blk_start +blk_len) data as of wconn.at database state.
//
// If vma != nil, created mapping is associated with that vma of user-space virtual memory manager:
// virtmem calls FileH::mmap under virtmem lock when virtmem fileh is mmapped into vma.
pair
<
Mapping
,
error
>
_FileH
::
mmap
(
int64_t
blk_start
,
int64_t
blk_len
,
VMA
*
vma
)
{
_FileH
&
f
=
*
this
;
xerr
::
Contextf
E
(
"%s: mmap f<%s> [blk%ld +blk%ld)"
,
v
(
f
.
wconn
),
v
(
f
.
foid
),
blk_start
,
blk_len
);
error
err
;
if
(
blk_start
<
0
)
panic
(
"blk_start < 0"
);
if
(
blk_len
<
0
)
panic
(
"blk_len < 0"
);
int64_t
blk_stop
;
// = blk_start + blk_len
if
(
__builtin_add_overflow
(
blk_start
,
blk_len
,
&
blk_stop
))
panic
(
"blk_start + blk_len overflow int64"
);
int64_t
stop
;
// = blk_stop *f.blksize;
if
(
__builtin_mul_overflow
(
blk_stop
,
f
.
blksize
,
&
stop
))
panic
(
"(blk_start + blk_len)*f.blksize overflow int64"
);
int64_t
start
=
blk_start
*
f
.
blksize
;
// NOTE virtmem lock is held by virtmem caller
// XXX locking
// XXX + wconn.atMu.RLock() ? -> y (e.g. f.headfsize is used)
// f.mu.lock()
// 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)
uint8_t
*
mem_start
,
*
mem_stop
;
tie
(
mem_start
,
err
)
=
mmap_ro
(
f
.
_headf
,
start
,
blk_len
*
f
.
blksize
);
if
(
err
!=
nil
)
return
make_pair
(
nil
,
E
(
err
));
mem_stop
=
mem_start
+
blk_len
*
f
.
blksize
;
bool
retok
=
false
;
defer
([
&
]()
{
if
(
!
retok
)
mm
::
unmap
(
mem_start
,
mem_stop
-
mem_start
);
// ignore error
});
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
)
return
make_pair
(
nil
,
E
(
err
));
}
Mapping
mmap
=
adoptref
(
new
_Mapping
());
mmap
->
fileh
=
newref
(
&
f
);
mmap
->
blk_start
=
blk_start
;
mmap
->
mem_start
=
mem_start
;
mmap
->
mem_stop
=
mem_stop
;
mmap
->
vma
=
vma
;
for
(
auto
_
:
f
.
_pinned
)
{
// TODO 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 ∉ this mapping
err
=
mmap
->
_remmapblk
(
blk
,
rev
);
if
(
err
!=
nil
)
return
make_pair
(
nil
,
E
(
err
));
}
if
(
vma
!=
nil
)
{
if
(
vma
->
mmap_overlay_server
!=
nil
)
panic
(
"vma is already associated with overlay server"
);
if
(
!
(
vma
->
addr_start
==
0
&&
vma
->
addr_stop
==
0
))
panic
(
"vma already covers !nil virtual memory area"
);
mmap
->
incref
();
// vma->mmap_overlay_server is keeping ref to mmap
vma
->
mmap_overlay_server
=
mmap
.
_ptr
();
vma
->
addr_start
=
(
uintptr_t
)
mmap
->
mem_start
;
vma
->
addr_stop
=
(
uintptr_t
)
mmap
->
mem_stop
;
mmap
->
_assertVMAOk
();
// just in case
}
f
.
_mmaps
.
push_back
(
mmap
);
// TODO keep f._mmaps ↑blk_start
retok
=
true
;
return
make_pair
(
mmap
,
nil
);
}
// unmap releases mapping memory from address space.
//
// After call to unmap the mapping must no longer be used.
// The association in between mapping and linked virtmem VMA is reset.
//
// Virtmem calls Mapping.unmap under virtmem lock when VMA is unmapped.
error
_Mapping
::
unmap
()
{
Mapping
mmap
=
newref
(
this
);
// XXX newref for std::remove
FileH
f
=
mmap
->
fileh
;
xerr
::
Contextf
E
(
"%s: f<%s>: unmap"
,
v
(
f
->
wconn
),
v
(
f
->
foid
));
// NOTE virtmem lock is held by virtmem caller
// XXX locking
// wconn.atMu.RLock() + f.mu.lock()
if
(
mmap
->
vma
!=
nil
)
{
mmap
->
_assertVMAOk
();
VMA
*
vma
=
mmap
->
vma
;
vma
->
mmap_overlay_server
=
nil
;
mmap
->
decref
();
// vma->mmap_overlay_server was holding a ref to mmap
vma
->
addr_start
=
0
;
vma
->
addr_stop
=
0
;
mmap
->
vma
=
nil
;
}
error
err
=
mm
::
unmap
(
mmap
->
mem_start
,
mmap
->
mem_stop
-
mmap
->
mem_start
);
mmap
->
mem_start
=
nil
;
mmap
->
mem_stop
=
nil
;
// XXX clear other fields?
// XXX do it first? (to avoid pinner going through f.mmaps and hitting unmapped memory)
//f->_mmaps.remove(mmap);
f
->
_mmaps
.
erase
(
std
::
remove
(
f
->
_mmaps
.
begin
(),
f
->
_mmaps
.
end
(),
mmap
),
f
->
_mmaps
.
end
());
return
E
(
err
);
}
// _remmapblk remmaps mapping memory for file[blk] to be viewing database as of @at state.
//
// at=TidHead means unpin to head/ .
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment