Commit c52b5571 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent f4afcf75
......@@ -109,9 +109,8 @@ public:
void decref();
public:
pair<FileH, error> open(zodb::Oid foid);
error close();
// XXX move mmap -> FileH
pair<Mapping, error> mmap(zodb::Oid foid, int64_t blk_start, int64_t blk_len);
error resync(zodb::Tid at);
private:
......@@ -140,10 +139,12 @@ struct _FileH : object {
private:
_FileH();
~_FileH();
// XXX -> friend Conn::open
friend pair<Mapping, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t blk_len);
friend pair<FileH, error> _Conn::open(zodb::Oid foid);
public:
void decref();
public:
pair<Mapping, error> mmap(int64_t blk_start, int64_t blk_len);
};
// Mapping represents one mapping of FileH.
......@@ -170,14 +171,12 @@ struct _Mapping : object {
private:
_Mapping();
~_Mapping();
// XXX -> friend FileH.mmap
friend pair<Mapping, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t blk_len);
friend pair<Mapping, error> _FileH::mmap(int64_t blk_start, int64_t blk_len);
public:
void decref();
};
} // wcfs::
#endif
......@@ -235,19 +235,11 @@ void _Conn::_pin1(PinReq *req) {
wconn._filehmu.unlock();
}
// 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) {
// open opens FileH corresponding to ZBigFile foid.
pair<FileH, error> _Conn::open(zodb::Oid foid) {
_Conn& wconn = *this;
// XXX err ctx
// XXX (blk_start + blk_len) * blk_size overflow
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; // XXX overflow
// XXX err ctx
wconn._filehmu.lock();
defer([&]() {
......@@ -257,65 +249,85 @@ pair<Mapping, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t blk_
FileH f; bool ok;
tie(f, ok) = wconn._filehtab.get(foid);
if (f == nil) {
f = adoptref(new _FileH());
f->wconn = newref(&wconn); // XXX newref -> simpler?
f->_foid = foid;
tie(f->_headf, err)
= wconn._wc->_open(fmt::sprintf("head/bigfile/%s", h_(foid)));
if (err != nil)
return make_pair(nil, err);
//f._pinned = {}
//f._mmaps = []
// XXX incref open count?
return make_pair(f, nil);
}
struct stat st;
err = f->_headf->stat(&st);
if (err != nil)
return make_pair(nil, err);
f->_blksize = st.st_blksize;
f->_headfsize = st.st_size;
if (!(f->_headfsize % f->_blksize == 0))
return make_pair(nil, fmt::errorf("wcfs bug: head/file size %% blksize != 0"));
// TODO perform open with filehmu released
wconn._filehtab[foid] = f;
f = adoptref(new _FileH());
f->wconn = newref(&wconn); // XXX newref -> simpler?
f->_foid = foid;
tie(f->_headf, err)
= wconn._wc->_open(fmt::sprintf("head/bigfile/%s", h_(foid)));
if (err != nil)
return make_pair(nil, err);
// start watching f
string ack;
tie(ack, err) = wconn._wlink->sendReq(context::background(), fmt::sprintf("watch %s @%s", h_(foid), h_(wconn.at)));
if (err != nil)
return make_pair(nil, err);
if (ack != "ok") {
// XXX unregister f from _filehtab
// 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()));
}
struct stat st;
err = f->_headf->stat(&st);
if (err != nil)
return make_pair(nil, err);
f->_blksize = st.st_blksize;
f->_headfsize = st.st_size;
if (!(f->_headfsize % f->_blksize == 0))
return make_pair(nil, fmt::errorf("wcfs bug: head/file size %% blksize != 0"));
wconn._filehtab[foid] = f;
// start watching f
string ack;
tie(ack, err) = wconn._wlink->sendReq(context::background(), fmt::sprintf("watch %s @%s", h_(foid), h_(wconn.at)));
if (err != nil)
return make_pair(nil, err);
if (ack != "ok") {
// XXX unregister f from _filehtab
// XXX vvv -> errctx?
return make_pair(nil, fmt::errorf("@%s: open f<%s>: watch: %s", h_(wconn.at), h_(foid), ack.c_str()));
}
// XXX relock wconn -> f ?
return make_pair(f, nil);
}
// mmap creates file mapping representing file[blk_start +blk_len) data as of wconn.at database state.
pair<Mapping, error> _FileH::mmap(int64_t blk_start, int64_t blk_len) {
_FileH& f = *this;
// XXX err ctx
// XXX (blk_start + blk_len) * blk_size overflow
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; // XXX overflow
// XXX f locking?
// 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)
int64_t start = blk_start*f->_blksize;
int64_t start = blk_start*f._blksize;
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)
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;
if (stop > f->_headfsize) {
uint8_t *zmem_start = mem_start + (max(f->_headfsize/*XXX -1 ?*/, start) - start);
int64_t stop = blk_stop*f._blksize;
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, err);
}
Mapping mmap = adoptref(new _Mapping());
mmap->fileh = f;
mmap->fileh = newref(&f); // XXX newref - simpler?
mmap->blk_start = blk_start;
mmap->mem_start = mem_start;
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;
zodb::Tid rev = _.second;
if (!(blk_start <= blk && blk < blk_stop))
......@@ -323,7 +335,7 @@ pair<Mapping, error> _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t blk_
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);
}
......
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