Commit c52b5571 authored by Kirill Smelkov's avatar Kirill Smelkov

.

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