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
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Joshua
wendelin.core
Commits
57489834
Commit
57489834
authored
Dec 09, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
ae23c2c3
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
156 additions
and
118 deletions
+156
-118
wcfs/__init__.py
wcfs/__init__.py
+2
-0
wcfs/internal/wcfs.h
wcfs/internal/wcfs.h
+83
-10
wcfs/internal/wcfs_virtmem.cpp
wcfs/internal/wcfs_virtmem.cpp
+71
-108
No files found.
wcfs/__init__.py
View file @
57489834
...
@@ -74,6 +74,8 @@ from .internal._wcfs import \
...
@@ -74,6 +74,8 @@ from .internal._wcfs import \
# Raw files on wcfs can be accessed with ._path/._read/._stat/._open .
# Raw files on wcfs can be accessed with ._path/._read/._stat/._open .
#
#
# WCFS logically mirrors ZODB.DB .
# WCFS logically mirrors ZODB.DB .
#
# XXX kill doc instead of C++.
class
WCFS
(
_WCFS
):
class
WCFS
(
_WCFS
):
# .mountpoint path to wcfs mountpoint
# .mountpoint path to wcfs mountpoint
# ._fwcfs /.wcfs/zurl opened to keep the server from going away (at least cleanly)
# ._fwcfs /.wcfs/zurl opened to keep the server from going away (at least cleanly)
...
...
wcfs/internal/wcfs.h
View file @
57489834
...
@@ -40,18 +40,33 @@ using std::pair;
...
@@ -40,18 +40,33 @@ using std::pair;
#include "wcfs_misc.h"
#include "wcfs_misc.h"
// from wendelin/bigfile/virtmem.h
extern
"C"
{
struct
BigFileH
;
}
// wcfs::
// wcfs::
namespace
wcfs
{
namespace
wcfs
{
struct
_File
;
typedef
refptr
<
struct
_Conn
>
Conn
;
struct
_Mapping
;
typedef
refptr
<
struct
_Mapping
>
Mapping
;
typedef
refptr
<
struct
_FileH
>
FileH
;
typedef
refptr
<
struct
_WatchLink
>
WatchLink
;
struct
PinReq
;
struct
PinReq
;
typedef
refptr
<
class
_Conn
>
Conn
;
typedef
refptr
<
class
_WatchLink
>
WatchLink
;
// WCFS represents filesystem-level connection to wcfs server.
// WCFS represents filesystem-level connection to wcfs server.
// XXX doc
//
// XXX Use join to create it?
//
// The primary way to access wcfs is to open logical connection viewing on-wcfs
// data as of particular database state, and use that logical connection to
// create base-layer mappings. See .connect and Conn for details.
//
// XXX raw files?
//
// WCFS logically mirrors ZODB.DB .
struct
WCFS
{
struct
WCFS
{
string
mountpoint
;
string
mountpoint
;
...
@@ -69,7 +84,7 @@ struct WCFS {
...
@@ -69,7 +84,7 @@ struct WCFS {
// cache in OS pagecache of /head/bigfile/*.
// cache in OS pagecache of /head/bigfile/*.
//
//
// Use WCFS.connect(at) to create Conn.
// Use WCFS.connect(at) to create Conn.
// Use .
mmap to create new Mappings
.
// Use .
open to create new FileH
.
// Use .resync to resync Conn onto different database view.
// Use .resync to resync Conn onto different database view.
//
//
// Conn logically mirrors ZODB.Connection .
// Conn logically mirrors ZODB.Connection .
...
@@ -79,8 +94,8 @@ struct _Conn : object {
...
@@ -79,8 +94,8 @@ struct _Conn : object {
zodb
::
Tid
at
;
zodb
::
Tid
at
;
WatchLink
_wlink
;
// watch/receive pins for created mappings
WatchLink
_wlink
;
// watch/receive pins for created mappings
sync
::
Mutex
_file
mu
;
sync
::
Mutex
_fileh
mu
;
dict
<
zodb
::
Oid
,
_File
*>
_filetab
;
// {} foid -> _file
dict
<
zodb
::
Oid
,
FileH
>
_filehtab
;
// {} foid -> fileh
sync
::
WorkGroup
_pinWG
;
sync
::
WorkGroup
_pinWG
;
func
<
void
()
>
_pinCancel
;
func
<
void
()
>
_pinCancel
;
...
@@ -95,8 +110,8 @@ public:
...
@@ -95,8 +110,8 @@ public:
public:
public:
error
close
();
error
close
();
// XXX move mmap ->
_FileH ?
// XXX move mmap ->
FileH
pair
<
_Mapping
*
,
error
>
mmap
(
zodb
::
Oid
foid
,
int64_t
blk_start
,
int64_t
blk_len
);
pair
<
Mapping
,
error
>
mmap
(
zodb
::
Oid
foid
,
int64_t
blk_start
,
int64_t
blk_len
);
error
resync
(
zodb
::
Tid
at
);
error
resync
(
zodb
::
Tid
at
);
private:
private:
...
@@ -104,6 +119,64 @@ private:
...
@@ -104,6 +119,64 @@ private:
void
_pin1
(
PinReq
*
req
);
void
_pin1
(
PinReq
*
req
);
};
};
// FileH represent isolated file view under Conn.
//
// The file view is maintained to be as of @Conn.at database state.
// The file view uses /head/<file>/data primarilty and @revX/<file>/data pin overrides.
//
// Use .mmap to map file view into memory.
typedef
refptr
<
struct
_FileH
>
FileH
;
struct
_FileH
:
object
{
Conn
wconn
;
zodb
::
Oid
_foid
;
// ZBigFile root object ID
size_t
_blksize
;
// block size of this file XXX -> off_t ?
os
::
File
_headf
;
// file object of head/file
off_t
_headfsize
;
// head/file size is known to be at least headfsize (size ↑=)
dict
<
int64_t
,
zodb
::
Tid
>
_pinned
;
// {} blk -> rev that wcfs already sent us for this file
vector
<
Mapping
>
_mmaps
;
// []Mapping ↑blk_start mappings of this file
// don't new - create via Conn.open
private:
_FileH
();
~
_FileH
();
// XXX -> friend Conn::open
friend
pair
<
Mapping
,
error
>
_Conn
::
mmap
(
zodb
::
Oid
foid
,
int64_t
blk_start
,
int64_t
blk_len
);
public:
void
decref
();
};
// Mapping represents one mapping of FileH.
typedef
refptr
<
struct
_Mapping
>
Mapping
;
struct
_Mapping
:
object
{
FileH
fileh
;
int64_t
blk_start
;
// offset of this mapping in file
BigFileH
*
virt_fileh
;
// mmapped under this virtmem file handle XXX -> VMA XXX can be nil
uint8_t
*
mem_start
;
// mmapped memory [mem_start, mem_stop)
uint8_t
*
mem_stop
;
int64_t
blk_stop
()
const
{
//XXX reenable
//ASSERT((mem_stop - mem_start) % file->blksize == 0);
return
blk_start
+
(
mem_stop
-
mem_start
)
/
fileh
->
_blksize
;
}
error
_remmapblk
(
int64_t
blk
,
zodb
::
Tid
at
);
void
remmap_blk
(
int64_t
blk
);
void
unmap
();
// don't new - create via FileH.mmap
private:
_Mapping
();
~
_Mapping
();
// XXX -> friend FileH.mmap
friend
pair
<
Mapping
,
error
>
_Conn
::
mmap
(
zodb
::
Oid
foid
,
int64_t
blk_start
,
int64_t
blk_len
);
public:
void
decref
();
};
}
// wcfs::
}
// wcfs::
...
...
wcfs/internal/wcfs_virtmem.cpp
View file @
57489834
...
@@ -71,43 +71,6 @@ static error mmap_zero_into_ro(void *addr, size_t size);
...
@@ -71,43 +71,6 @@ static error mmap_zero_into_ro(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
);
// _File represent isolated file view under Conn.
//
// XXX doc XXX naming -> _FileView ?
// XXX -> refptr ?
struct
_File
{
Conn
wconn
;
zodb
::
Oid
foid
;
// ZBigFile root object ID
size_t
blksize
;
// block size of this file XXX -> off_t ?
os
::
File
headf
;
// file object of head/file
off_t
headfsize
;
// head/file size is known to be at least headfsize (size ↑=)
dict
<
int64_t
,
zodb
::
Tid
>
pinned
;
// {} blk -> rev that wcfs already sent us for this file
vector
<
_Mapping
*>
mmaps
;
// []_Mapping ↑blk_start mappings of this file
};
// _Mapping represents one mapping of _File.
// XXX -> refptr ?
struct
_Mapping
{
_File
*
file
;
int64_t
blk_start
;
// offset of this mapping in file
BigFileH
*
fileh
;
// mmapped under this file handle
uint8_t
*
mem_start
;
// mmapped memory [mem_start, mem_stop)
uint8_t
*
mem_stop
;
int64_t
blk_stop
()
const
{
//XXX reenable
//ASSERT((mem_stop - mem_start) % file->blksize == 0);
return
blk_start
+
(
mem_stop
-
mem_start
)
/
file
->
blksize
;
}
error
_remmapblk
(
int64_t
blk
,
zodb
::
Tid
at
);
void
remmap_blk
(
int64_t
blk
);
void
unmap
();
};
// connect creates new Conn viewing WCFS state as of @at.
// connect creates new Conn viewing WCFS state as of @at.
pair
<
Conn
,
error
>
WCFS
::
connect
(
zodb
::
Tid
at
)
{
pair
<
Conn
,
error
>
WCFS
::
connect
(
zodb
::
Tid
at
)
{
WCFS
*
wc
=
this
;
WCFS
*
wc
=
this
;
...
@@ -154,20 +117,20 @@ error _Conn::close() {
...
@@ -154,20 +117,20 @@ error _Conn::close() {
// close all files - both that have no mappings and that still have opened mappings.
// close all files - both that have no mappings and that still have opened mappings.
// XXX after file is closed mappings continue to survive, but we can no
// XXX after file is closed mappings continue to survive, but we can no
// longer maintain consistent view.
// longer maintain consistent view.
wconn
.
_filemu
.
lock
();
wconn
.
_file
h
mu
.
lock
();
defer
([
&
]()
{
defer
([
&
]()
{
wconn
.
_filemu
.
unlock
();
wconn
.
_file
h
mu
.
unlock
();
});
});
for
(
auto
_
:
wconn
.
_filetab
)
{
for
(
auto
_
:
wconn
.
_file
h
tab
)
{
auto
f
=
_
.
second
;
auto
f
=
_
.
second
;
f
->
headf
->
close
();
// XXX err
f
->
_
headf
->
close
();
// XXX err
f
->
headf
=
nil
;
f
->
_
headf
=
nil
;
// XXX stop watching f
// XXX stop watching f
}
}
wconn
.
_filetab
.
clear
();
wconn
.
_file
h
tab
.
clear
();
return
nil
;
return
nil
;
}
}
...
@@ -226,19 +189,19 @@ void _Conn::_pin1(PinReq *req) {
...
@@ -226,19 +189,19 @@ void _Conn::_pin1(PinReq *req) {
defer(_)
defer(_)
#endif
#endif
_File
*
f
;
FileH
f
;
bool
ok
;
bool
ok
;
wconn
.
_filemu
.
lock
();
wconn
.
_file
h
mu
.
lock
();
tie
(
f
,
ok
)
=
wconn
.
_filetab
.
get
(
req
->
foid
);
tie
(
f
,
ok
)
=
wconn
.
_file
h
tab
.
get
(
req
->
foid
);
if
(
!
ok
)
{
if
(
!
ok
)
{
wconn
.
_filemu
.
unlock
();
wconn
.
_file
h
mu
.
unlock
();
// XXX err = we are not watching the file - why wcfs sent us this update?
// XXX err = we are not watching the file - why wcfs sent us this update?
}
}
// XXX relock wconn -> f
// XXX relock wconn -> f
for
(
auto
mmap
:
f
->
mmaps
)
{
// XXX use ↑blk_start for binary search
for
(
auto
mmap
:
f
->
_
mmaps
)
{
// XXX use ↑blk_start for binary search
if
(
!
(
mmap
->
blk_start
<=
req
->
blk
&&
req
->
blk
<
mmap
->
blk_stop
()))
if
(
!
(
mmap
->
blk_start
<=
req
->
blk
&&
req
->
blk
<
mmap
->
blk_stop
()))
continue
;
// blk ∉ mmap
continue
;
// blk ∉ mmap
...
@@ -259,21 +222,21 @@ void _Conn::_pin1(PinReq *req) {
...
@@ -259,21 +222,21 @@ void _Conn::_pin1(PinReq *req) {
//trace("\t-> remmaped"); XXX
//trace("\t-> remmaped"); XXX
}
}
// update f.pinned
// update f.
_
pinned
// XXX do it before ^^^ remmapblk (so that e.g. concurrent
// XXX do it before ^^^ remmapblk (so that e.g. concurrent
// discard/writeout see correct f.pinned) ?
// discard/writeout see correct f.
_
pinned) ?
if
(
req
->
at
==
TidHead
)
{
if
(
req
->
at
==
TidHead
)
{
f
->
pinned
.
erase
(
req
->
blk
);
// unpin to @head
f
->
_
pinned
.
erase
(
req
->
blk
);
// unpin to @head
}
}
else
{
else
{
f
->
pinned
[
req
->
blk
]
=
req
->
at
;
f
->
_
pinned
[
req
->
blk
]
=
req
->
at
;
}
}
wconn
.
_filemu
.
unlock
();
wconn
.
_file
h
mu
.
unlock
();
}
}
// mmap creates file mapping representing file[blk_start +blk_len) data as of wconn.at database state.
// mmap creates file mapping representing file[blk_start +blk_len) data as of wconn.at database state.
pair
<
_Mapping
*
,
error
>
_Conn
::
mmap
(
zodb
::
Oid
foid
,
int64_t
blk_start
,
int64_t
blk_len
)
{
pair
<
Mapping
,
error
>
_Conn
::
mmap
(
zodb
::
Oid
foid
,
int64_t
blk_start
,
int64_t
blk_len
)
{
_Conn
&
wconn
=
*
this
;
_Conn
&
wconn
=
*
this
;
// XXX err ctx
// XXX err ctx
// XXX (blk_start + blk_len) * blk_size overflow
// XXX (blk_start + blk_len) * blk_size overflow
...
@@ -286,34 +249,34 @@ pair<_Mapping*, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t bl
...
@@ -286,34 +249,34 @@ pair<_Mapping*, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t bl
int64_t
blk_stop
=
blk_start
+
blk_len
;
// XXX overflow
int64_t
blk_stop
=
blk_start
+
blk_len
;
// XXX overflow
wconn
.
_filemu
.
lock
();
wconn
.
_file
h
mu
.
lock
();
defer
([
&
]()
{
defer
([
&
]()
{
wconn
.
_filemu
.
unlock
();
wconn
.
_file
h
mu
.
unlock
();
});
});
_File
*
f
;
bool
ok
;
FileH
f
;
bool
ok
;
tie
(
f
,
ok
)
=
wconn
.
_filetab
.
get
(
foid
);
tie
(
f
,
ok
)
=
wconn
.
_file
h
tab
.
get
(
foid
);
if
(
f
==
nil
)
{
if
(
f
==
nil
)
{
f
=
new
_File
();
// XXX free f on error return (will be automatic if f = refptr)
f
=
adoptref
(
new
_FileH
());
f
->
wconn
=
newref
(
&
wconn
);
// XXX newref -> simpler?
f
->
wconn
=
newref
(
&
wconn
);
// XXX newref -> simpler?
f
->
foid
=
foid
;
f
->
_foid
=
foid
;
tie
(
f
->
headf
,
err
)
tie
(
f
->
_
headf
,
err
)
=
wconn
.
_wc
->
_open
(
fmt
::
sprintf
(
"head/bigfile/%s"
,
h_
(
foid
)));
=
wconn
.
_wc
->
_open
(
fmt
::
sprintf
(
"head/bigfile/%s"
,
h_
(
foid
)));
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
make_pair
(
nil
,
err
);
return
make_pair
(
nil
,
err
);
//f.
pinned
= {}
//f.
_pinned
= {}
//f.
mmaps
= []
//f.
_mmaps
= []
struct
stat
st
;
struct
stat
st
;
err
=
f
->
headf
->
stat
(
&
st
);
err
=
f
->
_
headf
->
stat
(
&
st
);
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
make_pair
(
nil
,
err
);
return
make_pair
(
nil
,
err
);
f
->
blksize
=
st
.
st_blksize
;
f
->
_
blksize
=
st
.
st_blksize
;
f
->
headfsize
=
st
.
st_size
;
f
->
_
headfsize
=
st
.
st_size
;
if
(
!
(
f
->
headfsize
%
f
->
blksize
==
0
))
if
(
!
(
f
->
_headfsize
%
f
->
_
blksize
==
0
))
return
make_pair
(
nil
,
fmt
::
errorf
(
"wcfs bug: head/file size %% blksize != 0"
));
return
make_pair
(
nil
,
fmt
::
errorf
(
"wcfs bug: head/file size %% blksize != 0"
));
wconn
.
_filetab
[
foid
]
=
f
;
wconn
.
_file
h
tab
[
foid
]
=
f
;
// start watching f
// start watching f
string
ack
;
string
ack
;
...
@@ -321,7 +284,7 @@ pair<_Mapping*, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t bl
...
@@ -321,7 +284,7 @@ pair<_Mapping*, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t bl
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
make_pair
(
nil
,
err
);
return
make_pair
(
nil
,
err
);
if
(
ack
!=
"ok"
)
{
if
(
ack
!=
"ok"
)
{
// XXX unregister f from _filetab
// XXX unregister f from _file
h
tab
// XXX vvv -> errctx?
// XXX vvv -> errctx?
return
make_pair
(
nil
,
fmt
::
errorf
(
"@%s: mmap f<%s>[%zd +%zd): %s"
,
h_
(
wconn
.
at
),
h_
(
foid
),
blk_start
,
blk_len
,
ack
.
c_str
()));
return
make_pair
(
nil
,
fmt
::
errorf
(
"@%s: mmap f<%s>[%zd +%zd): %s"
,
h_
(
wconn
.
at
),
h_
(
foid
),
blk_start
,
blk_len
,
ack
.
c_str
()));
}
}
...
@@ -331,28 +294,28 @@ pair<_Mapping*, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t bl
...
@@ -331,28 +294,28 @@ pair<_Mapping*, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t bl
// create memory with head/f mapping and applied pins
// 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)
// mmap-in zeros after f.size (else access to memory after file.size will raise SIGBUS)
int64_t
start
=
blk_start
*
f
->
blksize
;
int64_t
start
=
blk_start
*
f
->
_
blksize
;
uint8_t
*
mem_start
,
*
mem_stop
;
uint8_t
*
mem_start
,
*
mem_stop
;
tie
(
mem_start
,
err
)
=
mmap_ro
(
f
->
headf
,
start
,
blk_len
*
f
->
blksize
);
tie
(
mem_start
,
err
)
=
mmap_ro
(
f
->
_headf
,
start
,
blk_len
*
f
->
_
blksize
);
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
make_pair
(
nil
,
err
);
return
make_pair
(
nil
,
err
);
mem_stop
=
mem_start
+
blk_len
*
f
->
blksize
;
mem_stop
=
mem_start
+
blk_len
*
f
->
_
blksize
;
int64_t
stop
=
blk_stop
*
f
->
blksize
;
int64_t
stop
=
blk_stop
*
f
->
_
blksize
;
if
(
stop
>
f
->
headfsize
)
{
if
(
stop
>
f
->
_
headfsize
)
{
uint8_t
*
zmem_start
=
mem_start
+
(
max
(
f
->
headfsize
/*XXX -1 ?*/
,
start
)
-
start
);
uint8_t
*
zmem_start
=
mem_start
+
(
max
(
f
->
_
headfsize
/*XXX -1 ?*/
,
start
)
-
start
);
err
=
mmap_zero_into_ro
(
zmem_start
,
mem_stop
-
zmem_start
);
err
=
mmap_zero_into_ro
(
zmem_start
,
mem_stop
-
zmem_start
);
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
make_pair
(
nil
,
err
);
return
make_pair
(
nil
,
err
);
}
}
_Mapping
*
mmap
=
new
_Mapping
(
);
Mapping
mmap
=
adoptref
(
new
_Mapping
()
);
mmap
->
file
=
f
;
mmap
->
file
h
=
f
;
mmap
->
blk_start
=
blk_start
;
mmap
->
blk_start
=
blk_start
;
mmap
->
mem_start
=
mem_start
;
mmap
->
mem_start
=
mem_start
;
mmap
->
mem_stop
=
mem_stop
;
mmap
->
mem_stop
=
mem_stop
;
for
(
auto
_
:
f
->
pinned
)
{
// XXX keep f.
pinned ↑blk and use binary search?
for
(
auto
_
:
f
->
_pinned
)
{
// XXX keep f._
pinned ↑blk and use binary search?
int64_t
blk
=
_
.
first
;
int64_t
blk
=
_
.
first
;
zodb
::
Tid
rev
=
_
.
second
;
zodb
::
Tid
rev
=
_
.
second
;
if
(
!
(
blk_start
<=
blk
&&
blk
<
blk_stop
))
if
(
!
(
blk_start
<=
blk
&&
blk
<
blk_stop
))
...
@@ -360,7 +323,7 @@ pair<_Mapping*, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t bl
...
@@ -360,7 +323,7 @@ pair<_Mapping*, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t bl
mmap
->
_remmapblk
(
blk
,
rev
);
// XXX err?
mmap
->
_remmapblk
(
blk
,
rev
);
// XXX err?
}
}
f
->
mmaps
.
push_back
(
mmap
);
// XXX keep f.
mmaps ↑blk_start
f
->
_mmaps
.
push_back
(
mmap
);
// XXX keep f._
mmaps ↑blk_start
return
make_pair
(
mmap
,
nil
);
return
make_pair
(
mmap
,
nil
);
}
}
...
@@ -372,42 +335,42 @@ error _Conn::resync(zodb::Tid at) {
...
@@ -372,42 +335,42 @@ error _Conn::resync(zodb::Tid at) {
// XXX locking
// XXX locking
for
(
auto
fit
:
wconn
.
_filetab
)
{
for
(
auto
fit
:
wconn
.
_file
h
tab
)
{
zodb
::
Oid
foid
=
fit
.
first
;
zodb
::
Oid
foid
=
fit
.
first
;
_File
&
f
=
*
fit
.
second
;
FileH
f
=
fit
.
second
;
// XXX if file has no mappings and was not used during whole prev
// XXX if file has no mappings and was not used during whole prev
// cycle - forget and stop watching it
// cycle - forget and stop watching it
// update f.headfsize and remmap to head/f zero regions that are now covered by head/f
// update f.
_
headfsize and remmap to head/f zero regions that are now covered by head/f
struct
stat
st
;
struct
stat
st
;
error
err
=
f
.
headf
->
stat
(
&
st
);
error
err
=
f
->
_
headf
->
stat
(
&
st
);
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
err
;
return
err
;
if
((
size_t
)
st
.
st_blksize
!=
f
.
blksize
)
// blksize must not change
if
((
size_t
)
st
.
st_blksize
!=
f
->
_blksize
)
// blksize must not change
return
fmt
::
errorf
(
"wcfs bug: blksize changed: %zd -> %ld"
,
f
.
blksize
,
st
.
st_blksize
);
return
fmt
::
errorf
(
"wcfs bug: blksize changed: %zd -> %ld"
,
f
->
_
blksize
,
st
.
st_blksize
);
auto
headfsize
=
st
.
st_size
;
auto
headfsize
=
st
.
st_size
;
if
(
!
(
f
.
headfsize
<=
headfsize
))
// head/file size ↑=
if
(
!
(
f
->
_
headfsize
<=
headfsize
))
// head/file size ↑=
return
fmt
::
errorf
(
"wcfs bug: head/file size not ↑="
);
return
fmt
::
errorf
(
"wcfs bug: head/file size not ↑="
);
if
(
!
(
headfsize
%
f
.
blksize
==
0
))
if
(
!
(
headfsize
%
f
->
_
blksize
==
0
))
return
fmt
::
errorf
(
"wcfs bug: head/file size %% blksize != 0"
);
return
fmt
::
errorf
(
"wcfs bug: head/file size %% blksize != 0"
);
for
(
auto
mmap
:
f
.
mmaps
)
{
for
(
auto
mmap
:
f
->
_
mmaps
)
{
printf
(
" resync -> %s: unzero [%lu:%lu)"
,
h_
(
at
),
f
.
headfsize
/
f
.
blksize
,
headfsize
/
f
.
blksize
);
printf
(
" resync -> %s: unzero [%lu:%lu)"
,
h_
(
at
),
f
->
_headfsize
/
f
->
_blksize
,
headfsize
/
f
->
_
blksize
);
uint8_t
*
mem_unzero_start
=
min
(
mmap
->
mem_stop
,
uint8_t
*
mem_unzero_start
=
min
(
mmap
->
mem_stop
,
mmap
->
mem_start
+
(
f
.
headfsize
-
mmap
->
blk_start
*
f
.
blksize
));
mmap
->
mem_start
+
(
f
->
_headfsize
-
mmap
->
blk_start
*
f
->
_
blksize
));
uint8_t
*
mem_unzero_stop
=
min
(
mmap
->
mem_stop
,
uint8_t
*
mem_unzero_stop
=
min
(
mmap
->
mem_stop
,
mmap
->
mem_start
+
(
headfsize
-
mmap
->
blk_start
*
f
.
blksize
));
mmap
->
mem_start
+
(
headfsize
-
mmap
->
blk_start
*
f
->
_
blksize
));
if
(
mem_unzero_stop
-
mem_unzero_start
>
0
)
{
if
(
mem_unzero_stop
-
mem_unzero_start
>
0
)
{
err
=
mmap_into_ro
(
mem_unzero_start
,
mem_unzero_stop
-
mem_unzero_start
,
f
.
headf
,
f
.
headfsize
);
err
=
mmap_into_ro
(
mem_unzero_start
,
mem_unzero_stop
-
mem_unzero_start
,
f
->
_headf
,
f
->
_
headfsize
);
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
err
;
return
err
;
}
}
}
}
f
.
headfsize
=
headfsize
;
f
->
_
headfsize
=
headfsize
;
string
ack
;
string
ack
;
...
@@ -415,7 +378,7 @@ error _Conn::resync(zodb::Tid at) {
...
@@ -415,7 +378,7 @@ error _Conn::resync(zodb::Tid at) {
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
err
;
return
err
;
if
(
ack
!=
"ok"
)
{
if
(
ack
!=
"ok"
)
{
// XXX unregister f from _filetab
// XXX unregister f from _file
h
tab
// XXX vvv -> errctx?
// XXX vvv -> errctx?
return
fmt
::
errorf
(
"resync @%s -> @%s: f<%s>: %s"
,
h_
(
wconn
.
at
),
h_
(
at
),
h_
(
foid
),
ack
.
c_str
());
return
fmt
::
errorf
(
"resync @%s -> @%s: f<%s>: %s"
,
h_
(
wconn
.
at
),
h_
(
at
),
h_
(
foid
),
ack
.
c_str
());
}
}
...
@@ -435,19 +398,19 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
...
@@ -435,19 +398,19 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
//XXX reenable
//XXX reenable
//ASSERT(mmap->blk_start <= blk && blk < mmap->blk_stop());
//ASSERT(mmap->blk_start <= blk && blk < mmap->blk_stop());
_File
*
f
=
mmap
->
file
;
FileH
f
=
mmap
->
fileh
;
error
err
;
error
err
;
uint8_t
*
blkmem
=
mmap
->
mem_start
+
(
blk
-
mmap
->
blk_start
)
*
f
->
blksize
;
uint8_t
*
blkmem
=
mmap
->
mem_start
+
(
blk
-
mmap
->
blk_start
)
*
f
->
_
blksize
;
os
::
File
fsfile
;
os
::
File
fsfile
;
bool
fclose
=
false
;
bool
fclose
=
false
;
if
(
at
==
TidHead
)
{
if
(
at
==
TidHead
)
{
fsfile
=
f
->
headf
;
fsfile
=
f
->
_
headf
;
}
}
else
{
else
{
// TODO share @rev fd until wconn is resynced?
// TODO share @rev fd until wconn is resynced?
tie
(
fsfile
,
err
)
=
f
->
wconn
->
_wc
->
_open
(
tie
(
fsfile
,
err
)
=
f
->
wconn
->
_wc
->
_open
(
fmt
::
sprintf
(
"@%s/bigfile/%s"
,
h_
(
at
),
h_
(
f
->
foid
)));
fmt
::
sprintf
(
"@%s/bigfile/%s"
,
h_
(
at
),
h_
(
f
->
_
foid
)));
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
err
;
return
err
;
fclose
=
true
;
fclose
=
true
;
...
@@ -461,19 +424,19 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
...
@@ -461,19 +424,19 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
err
=
fsfile
->
stat
(
&
st
);
err
=
fsfile
->
stat
(
&
st
);
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
err
;
return
err
;
if
((
size_t
)
st
.
st_blksize
!=
f
->
blksize
)
if
((
size_t
)
st
.
st_blksize
!=
f
->
_
blksize
)
return
fmt
::
errorf
(
"wcfs bug: blksize changed: %zd -> %ld"
,
f
->
blksize
,
st
.
st_blksize
);
return
fmt
::
errorf
(
"wcfs bug: blksize changed: %zd -> %ld"
,
f
->
_
blksize
,
st
.
st_blksize
);
// block is beyond file size - mmap with zeros - else access to memory
// block is beyond file size - mmap with zeros - else access to memory
// after file.size will raise SIGBUS. (assumes head/f size ↑=)
// after file.size will raise SIGBUS. (assumes head/f size ↑=)
if
((
blk
+
1
)
*
f
->
blksize
>
(
size_t
)
st
.
st_size
)
{
if
((
blk
+
1
)
*
f
->
_
blksize
>
(
size_t
)
st
.
st_size
)
{
err
=
mmap_zero_into_ro
(
blkmem
,
1
*
f
->
blksize
);
err
=
mmap_zero_into_ro
(
blkmem
,
1
*
f
->
_
blksize
);
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
err
;
return
err
;
}
}
// block is inside file - mmap file data
// block is inside file - mmap file data
else
{
else
{
err
=
mmap_into_ro
(
blkmem
,
1
*
f
->
blksize
,
fsfile
,
blk
*
f
->
blksize
);
err
=
mmap_into_ro
(
blkmem
,
1
*
f
->
_blksize
,
fsfile
,
blk
*
f
->
_
blksize
);
if
(
err
!=
nil
)
if
(
err
!=
nil
)
return
err
;
return
err
;
}
}
...
@@ -492,7 +455,7 @@ void _Mapping::remmap_blk(int64_t blk) {
...
@@ -492,7 +455,7 @@ void _Mapping::remmap_blk(int64_t blk) {
// blkrev = rev | @head
// blkrev = rev | @head
zodb
::
Tid
blkrev
;
bool
ok
;
zodb
::
Tid
blkrev
;
bool
ok
;
tie
(
blkrev
,
ok
)
=
mmap
.
file
->
pinned
.
get
(
blk
);
tie
(
blkrev
,
ok
)
=
mmap
.
file
h
->
_
pinned
.
get
(
blk
);
if
(
!
ok
)
if
(
!
ok
)
blkrev
=
TidHead
;
blkrev
=
TidHead
;
...
@@ -502,7 +465,7 @@ void _Mapping::remmap_blk(int64_t blk) {
...
@@ -502,7 +465,7 @@ void _Mapping::remmap_blk(int64_t blk) {
// unmap removes mapping memory from address space.
// unmap removes mapping memory from address space.
// virtmem calls this when VMA is unmapped.
// virtmem calls this when VMA is unmapped.
void
_Mapping
::
unmap
()
{
void
_Mapping
::
unmap
()
{
_Mapping
*
mmap
=
this
;
Mapping
mmap
=
newref
(
this
);
// XXX newref for std::remove
// XXX locking
// XXX locking
...
@@ -513,9 +476,9 @@ void _Mapping::unmap() {
...
@@ -513,9 +476,9 @@ void _Mapping::unmap() {
mmap
->
mem_stop
=
NULL
;
mmap
->
mem_stop
=
NULL
;
// XXX clear other fields?
// XXX clear other fields?
_File
*
f
=
mmap
->
file
;
FileH
f
=
mmap
->
fileh
;
//f->mmaps.remove(mmap);
//f->
_
mmaps.remove(mmap);
std
::
remove
(
f
->
mmaps
.
begin
(),
f
->
mmaps
.
end
(),
mmap
);
// XXX keep mmaps sorted
std
::
remove
(
f
->
_mmaps
.
begin
(),
f
->
_
mmaps
.
end
(),
mmap
);
// XXX keep mmaps sorted
}
}
...
...
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