Commit b6685340 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent cd3f3f04
...@@ -224,12 +224,14 @@ void Conn::_pin1(SrvReq *req) { ...@@ -224,12 +224,14 @@ void Conn::_pin1(SrvReq *req) {
// at=None means unpin to head/ . XXX -> C // at=None means unpin to head/ . XXX -> C
// NOTE this does not check wrt virtmem already mapped blk as RW. // NOTE this does not check wrt virtmem already mapped blk as RW.
void _Mapping::_remmapblk(int64_t blk, Tid at) { void _Mapping::_remmapblk(int64_t blk, Tid at) {
// XXX err context?
_Mapping *mmap = this; _Mapping *mmap = this;
ASSERT(mmap->blk_start <= blk && blk < mmap->blk_stop()); ASSERT(mmap->blk_start <= blk && blk < mmap->blk_stop());
_File *f = mmap->file; _File *f = mmap->file;
uint8_t *blkmem = mmap->mem_start + (blk - mmap->blk_start)*f->blksize; uint8_t *blkmem = mmap->mem_start + (blk - mmap->blk_start)*f->blksize;
osfile fsfile;
if (at == TidHead) { if (at == TidHead) {
fsfile = f->headf; fsfile = f->headf;
} }
...@@ -239,15 +241,65 @@ void _Mapping::_remmapblk(int64_t blk, Tid at) { ...@@ -239,15 +241,65 @@ void _Mapping::_remmapblk(int64_t blk, Tid at) {
defer(fsfile.close) defer(fsfile.close)
} }
_ = os.fstat(fsfile.fileno()); struct stat st;
ASSERT(_.st_blksize == f->blksize); // FIXME assert err = fsfile.stat(&st);
if (err != nil)
return err;
ASSERT(st.st_blksize == f->blksize); // FIXME assert
// block is beyond file size - mmap with zeros (assumes head/f size ↑=) // block is beyond file size - mmap with zeros (assumes head/f size ↑=)
if ((blk+1)*f->blksize > _.st_size) { if ((blk+1)*f->blksize > st.st_size) {
mm.map_zero_into_ro(blkmem) mm.map_zero_into_ro(blkmem);
} }
// block is inside file - mmap file data // block is inside file - mmap file data
else { else {
mm.map_into_ro(blkmem, fsfile.fileno(), blk*f->blksize) mm.map_into_ro(blkmem, fsfile.fileno(), blk*f->blksize);
} }
} }
struct error {
err string;
error() {}
error(nullptr_t) {} // = nil
bool operator==(nullptr_t) { // == nil
return err.is_empty();
}
bool operator!=(nullptr_t) { // != nil
return !(this==nil);
}
};
struct osfile {
int fd;
string path;
error close();
error stat(struct stat *st);
};
error osfile::close() {
osfile *f = this;
int err = close(f->fd);
if (err != 0)
return f->_errno("close");
}
error osfile::stat(struct stat *st) {
osfile *f = this;
int err = fstat(f->fd, st);
if (err != 0)
return f->_errno("stat");
return nil;
}
// _errno returns error corresponding to op and errno.
error osfile::_err(const char *op) {
return errorf("%s %s: %s", op, f->path, strerror_r(errno));
}
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