These include: - Checking memory allocations - Using smart pointers where possible - Using static_cast instead of reinterpret_cast or C-style cast where possible - Formatting and consistency
Signed-off-by: Fotis Xenakis <[email protected]> --- fs/virtiofs/virtiofs.hh | 2 +- fs/virtiofs/virtiofs_i.hh | 19 +- fs/virtiofs/virtiofs_vfsops.cc | 136 +++++++------- fs/virtiofs/virtiofs_vnops.cc | 318 ++++++++++++++++++--------------- 4 files changed, 245 insertions(+), 230 deletions(-) diff --git a/fs/virtiofs/virtiofs.hh b/fs/virtiofs/virtiofs.hh index 892c9ca7..475d5eba 100644 --- a/fs/virtiofs/virtiofs.hh +++ b/fs/virtiofs/virtiofs.hh @@ -32,7 +32,7 @@ struct virtiofs_file_data { uint64_t file_handle; }; -void virtiofs_set_vnode(struct vnode *vnode, struct virtiofs_inode *inode); +void virtiofs_set_vnode(struct vnode* vnode, struct virtiofs_inode* inode); extern struct vfsops virtiofs_vfsops; extern struct vnops virtiofs_vnops; diff --git a/fs/virtiofs/virtiofs_i.hh b/fs/virtiofs/virtiofs_i.hh index c5dc10d2..17fbcd36 100644 --- a/fs/virtiofs/virtiofs_i.hh +++ b/fs/virtiofs/virtiofs_i.hh @@ -12,15 +12,14 @@ #include <osv/mutex.h> #include <osv/waitqueue.hh> -struct fuse_request -{ +struct fuse_request { struct fuse_in_header in_header; struct fuse_out_header out_header; - void *input_args_data; + void* input_args_data; size_t input_args_size; - void *output_args_data; + void* output_args_data; size_t output_args_size; mutex_t req_mutex; @@ -28,14 +27,14 @@ struct fuse_request }; struct fuse_strategy { - void *drv; - int (*make_request)(void*, struct fuse_request*); + void* drv; + int (*make_request)(void*, fuse_request*); }; -int fuse_req_send_and_receive_reply(fuse_strategy* strategy, uint32_t opcode, uint64_t nodeid, - void *input_args_data, size_t input_args_size, - void *output_args_data, size_t output_args_size); +int fuse_req_send_and_receive_reply(fuse_strategy* strategy, uint32_t opcode, + uint64_t nodeid, void* input_args_data, size_t input_args_size, + void* output_args_data, size_t output_args_size); -void fuse_req_wait(struct fuse_request* req); +void fuse_req_wait(fuse_request* req); #endif diff --git a/fs/virtiofs/virtiofs_vfsops.cc b/fs/virtiofs/virtiofs_vfsops.cc index 4e8bf26e..968f93fc 100644 --- a/fs/virtiofs/virtiofs_vfsops.cc +++ b/fs/virtiofs/virtiofs_vfsops.cc @@ -13,36 +13,21 @@ #include "virtiofs.hh" #include "virtiofs_i.hh" -static int virtiofs_mount(struct mount *mp, const char *dev, int flags, const void *data); -static int virtiofs_sync(struct mount *mp); -static int virtiofs_statfs(struct mount *mp, struct statfs *statp); -static int virtiofs_unmount(struct mount *mp, int flags); +static std::atomic<uint64_t> fuse_unique_id(1); -#define virtiofs_vget ((vfsop_vget_t)vfs_nullop) - -struct vfsops virtiofs_vfsops = { - virtiofs_mount, /* mount */ - virtiofs_unmount, /* unmount */ - virtiofs_sync, /* sync */ - virtiofs_vget, /* vget */ - virtiofs_statfs, /* statfs */ - &virtiofs_vnops /* vnops */ -}; - -std::atomic<uint64_t> fuse_unique_id(1); - -int fuse_req_send_and_receive_reply(fuse_strategy* strategy, uint32_t opcode, uint64_t nodeid, - void *input_args_data, size_t input_args_size, void *output_args_data, size_t output_args_size) +int fuse_req_send_and_receive_reply(fuse_strategy* strategy, uint32_t opcode, + uint64_t nodeid, void* input_args_data, size_t input_args_size, + void* output_args_data, size_t output_args_size) { - auto *req = new (std::nothrow) fuse_request(); - - req->in_header.len = 0; //TODO + std::unique_ptr<fuse_request> req {new (std::nothrow) fuse_request()}; + if (!req) { + return ENOMEM; + } + req->in_header.len = sizeof(req->in_header) + input_args_size; req->in_header.opcode = opcode; - req->in_header.unique = fuse_unique_id.fetch_add(1, std::memory_order_relaxed); + req->in_header.unique = fuse_unique_id.fetch_add(1, + std::memory_order_relaxed); req->in_header.nodeid = nodeid; - req->in_header.uid = 0; - req->in_header.gid = 0; - req->in_header.pid = 0; req->input_args_data = input_args_data; req->input_args_size = input_args_size; @@ -51,18 +36,17 @@ int fuse_req_send_and_receive_reply(fuse_strategy* strategy, uint32_t opcode, ui req->output_args_size = output_args_size; assert(strategy->drv); - strategy->make_request(strategy->drv, req); - fuse_req_wait(req); + strategy->make_request(strategy->drv, req.get()); + fuse_req_wait(req.get()); int error = -req->out_header.error; - delete req; return error; } -void virtiofs_set_vnode(struct vnode *vnode, struct virtiofs_inode *inode) +void virtiofs_set_vnode(struct vnode* vnode, struct virtiofs_inode* inode) { - if (vnode == nullptr || inode == nullptr) { + if (!vnode || !inode) { return; } @@ -82,81 +66,85 @@ void virtiofs_set_vnode(struct vnode *vnode, struct virtiofs_inode *inode) vnode->v_size = inode->attr.size; } -static int -virtiofs_mount(struct mount *mp, const char *dev, int flags, const void *data) { - struct device *device; - int error = -1; +static int virtiofs_mount(struct mount* mp, const char* dev, int flags, + const void* data) +{ + struct device* device; - error = device_open(dev + 5, DO_RDWR, &device); + int error = device_open(dev + strlen("/dev/"), DO_RDWR, &device); if (error) { kprintf("[virtiofs] Error opening device!\n"); return error; } - mp->m_dev = device; - - auto *in_args = new(std::nothrow) fuse_init_in(); + std::unique_ptr<fuse_init_in> in_args {new (std::nothrow) fuse_init_in()}; + std::unique_ptr<fuse_init_out> out_args {new (std::nothrow) fuse_init_out}; + if (!in_args || !out_args) { + return ENOMEM; + } in_args->major = FUSE_KERNEL_VERSION; in_args->minor = FUSE_KERNEL_MINOR_VERSION; in_args->max_readahead = PAGE_SIZE; - in_args->flags = 0; //TODO Investigate which flags to set - - auto *out_args = new(std::nothrow) fuse_init_out(); + in_args->flags = 0; // TODO: Verify that we need not set any flag - auto *strategy = reinterpret_cast<fuse_strategy *>(device->private_data); + auto* strategy = static_cast<fuse_strategy*>(device->private_data); error = fuse_req_send_and_receive_reply(strategy, FUSE_INIT, FUSE_ROOT_ID, - in_args, sizeof(*in_args), out_args, sizeof(*out_args)); - - if (!error) { - virtiofs_debug("Initialized fuse filesystem with version major: %d, minor: %d\n", - out_args->major, out_args->minor); - - auto *root_node = new virtiofs_inode(); - root_node->nodeid = FUSE_ROOT_ID; - root_node->attr.mode = S_IFDIR; + in_args.get(), sizeof(*in_args), out_args.get(), sizeof(*out_args)); + if (error) { + kprintf("[virtiofs] Failed to initialize fuse filesystem!\n"); + return error; + } + // TODO: Handle version negotiation - virtiofs_set_vnode(mp->m_root->d_vnode, root_node); + virtiofs_debug("Initialized fuse filesystem with version major: %d, " + "minor: %d\n", out_args->major, out_args->minor); - mp->m_data = strategy; - mp->m_dev = device; - } else { - kprintf("[virtiofs] Failed to initialized fuse filesystem!\n"); + auto* root_node {new (std::nothrow) virtiofs_inode()}; + if (!root_node) { + return ENOMEM; } + root_node->nodeid = FUSE_ROOT_ID; + root_node->attr.mode = S_IFDIR; - delete out_args; - delete in_args; + virtiofs_set_vnode(mp->m_root->d_vnode, root_node); - return error; -} + mp->m_data = strategy; + mp->m_dev = device; -static int virtiofs_sync(struct mount *mp) { return 0; } -static int virtiofs_statfs(struct mount *mp, struct statfs *statp) +static int virtiofs_sync(struct mount* mp) { - //TODO - //struct virtiofs_info *virtiofs = (struct virtiofs_info *) mp->m_data; + return 0; +} - //statp->f_bsize = sb->block_size; +static int virtiofs_statfs(struct mount* mp, struct statfs* statp) +{ + // TODO: Call FUSE_STATFS - // Total blocks - //statp->f_blocks = sb->structure_info_blocks_count + sb->structure_info_first_block; // Read only. 0 blocks free statp->f_bfree = 0; statp->f_bavail = 0; statp->f_ffree = 0; - //statp->f_files = sb->inodes_count; //Needs to be inode count - - statp->f_namelen = 0; //FIXME return 0; } -static int -virtiofs_unmount(struct mount *mp, int flags) +static int virtiofs_unmount(struct mount* mp, int flags) { - struct device *dev = mp->m_dev; + struct device* dev = mp->m_dev; return device_close(dev); } + +#define virtiofs_vget ((vfsop_vget_t)vfs_nullop) + +struct vfsops virtiofs_vfsops = { + virtiofs_mount, /* mount */ + virtiofs_unmount, /* unmount */ + virtiofs_sync, /* sync */ + virtiofs_vget, /* vget */ + virtiofs_statfs, /* statfs */ + &virtiofs_vnops /* vnops */ +}; diff --git a/fs/virtiofs/virtiofs_vnops.cc b/fs/virtiofs/virtiofs_vnops.cc index 3c212274..7fbb2cd2 100644 --- a/fs/virtiofs/virtiofs_vnops.cc +++ b/fs/virtiofs/virtiofs_vnops.cc @@ -27,206 +27,233 @@ #include "virtiofs.hh" #include "virtiofs_i.hh" -#define VERIFY_READ_INPUT_ARGUMENTS() \ - /* Cant read directories */\ - if (vnode->v_type == VDIR) \ - return EISDIR; \ - /* Cant read anything but reg */\ - if (vnode->v_type != VREG) \ - return EINVAL; \ - /* Cant start reading before the first byte */\ - if (uio->uio_offset < 0) \ - return EINVAL; \ - /* Need to read more than 1 byte */\ - if (uio->uio_resid == 0) \ - return 0; \ - /* Cant read after the end of the file */\ - if (uio->uio_offset >= (off_t)vnode->v_size) \ - return 0; +static constexpr uint32_t OPEN_FLAGS = O_RDONLY; -int virtiofs_init(void) { +int virtiofs_init() +{ return 0; } -static int virtiofs_lookup(struct vnode *vnode, char *name, struct vnode **vpp) +static int virtiofs_lookup(struct vnode* vnode, char* name, struct vnode** vpp) { - struct virtiofs_inode *inode = (struct virtiofs_inode *) vnode->v_data; - struct vnode *vp = nullptr; + auto* inode = static_cast<virtiofs_inode*>(vnode->v_data); if (*name == '\0') { return ENOENT; } if (!S_ISDIR(inode->attr.mode)) { - kprintf("[virtiofs] inode:%d, ABORTED lookup of %s because not a directory\n", inode->nodeid, name); + kprintf("[virtiofs] inode:%lld, ABORTED lookup of %s because not a " + "directory\n", inode->nodeid, name); return ENOTDIR; } - auto *out_args = new (std::nothrow) fuse_entry_out(); - auto input = new char[strlen(name) + 1]; - strcpy(input, name); - - auto *strategy = reinterpret_cast<fuse_strategy*>(vnode->v_mount->m_data); - int error = fuse_req_send_and_receive_reply(strategy, FUSE_LOOKUP, inode->nodeid, - input, strlen(name) + 1, out_args, sizeof(*out_args)); - - if (!error) { - if (vget(vnode->v_mount, out_args->nodeid, &vp)) { //TODO: Will it ever work? Revisit - virtiofs_debug("lookup found vp in cache!\n"); - *vpp = vp; - return 0; - } - - auto *new_inode = new virtiofs_inode(); - new_inode->nodeid = out_args->nodeid; - virtiofs_debug("inode %d, lookup found inode %d for %s!\n", inode->nodeid, new_inode->nodeid, name); - memcpy(&new_inode->attr, &out_args->attr, sizeof(out_args->attr)); + auto in_args_len = strlen(name) + 1; + std::unique_ptr<char[]> in_args {new (std::nothrow) char[in_args_len]}; + std::unique_ptr<fuse_entry_out> out_args { + new (std::nothrow) fuse_entry_out}; + if (!out_args || !in_args) { + return ENOMEM; + } + strcpy(in_args.get(), name); + + auto* strategy = static_cast<fuse_strategy*>(vnode->v_mount->m_data); + auto error = fuse_req_send_and_receive_reply(strategy, FUSE_LOOKUP, + inode->nodeid, in_args.get(), in_args_len, out_args.get(), + sizeof(*out_args)); + if (error) { + kprintf("[virtiofs] inode:%lld, lookup failed to find %s\n", + inode->nodeid, name); + // TODO: Implement proper error handling by sending FUSE_FORGET + return error; + } - virtiofs_set_vnode(vp, new_inode); + struct vnode* vp; + // TODO OPT: Should we even use the cache? (consult spec on metadata) + if (vget(vnode->v_mount, out_args->nodeid, &vp) == 1) { + virtiofs_debug("lookup found vp in cache!\n"); *vpp = vp; - } else { - kprintf("[virtiofs] inode:%d, lookup failed to find %s\n", inode->nodeid, name); - //TODO Implement proper error handling by sending FUSE_FORGET + return 0; } - delete input; - delete out_args; + auto* new_inode = new (std::nothrow) virtiofs_inode; + if (!new_inode) { + return ENOMEM; + } + new_inode->nodeid = out_args->nodeid; + virtiofs_debug("inode %lld, lookup found inode %lld for %s!\n", + inode->nodeid, new_inode->nodeid, name); + memcpy(&new_inode->attr, &out_args->attr, sizeof(out_args->attr)); - return error; + virtiofs_set_vnode(vp, new_inode); + *vpp = vp; + + return 0; } -static int virtiofs_open(struct file *fp) +static int virtiofs_open(struct file* fp) { if ((file_flags(fp) & FWRITE)) { - // Do no allow opening files to write - return (EROFS); + // Do not allow opening files to write + return EROFS; } - struct vnode *vnode = file_dentry(fp)->d_vnode; - struct virtiofs_inode *inode = (struct virtiofs_inode *) vnode->v_data; + auto* vnode = file_dentry(fp)->d_vnode; + auto* inode = static_cast<virtiofs_inode*>(vnode->v_data); - auto *out_args = new (std::nothrow) fuse_open_out(); - auto *input_args = new (std::nothrow) fuse_open_in(); - input_args->flags = O_RDONLY; - - auto *strategy = reinterpret_cast<fuse_strategy*>(vnode->v_mount->m_data); - int error = fuse_req_send_and_receive_reply(strategy, FUSE_OPEN, inode->nodeid, - input_args, sizeof(*input_args), out_args, sizeof(*out_args)); + std::unique_ptr<fuse_open_in> in_args {new (std::nothrow) fuse_open_in()}; + std::unique_ptr<fuse_open_out> out_args {new (std::nothrow) fuse_open_out}; + if (!out_args || !in_args) { + return ENOMEM; + } + in_args->flags = OPEN_FLAGS; + + auto* strategy = static_cast<fuse_strategy*>(vnode->v_mount->m_data); + auto error = fuse_req_send_and_receive_reply(strategy, FUSE_OPEN, + inode->nodeid, in_args.get(), sizeof(*in_args), out_args.get(), + sizeof(*out_args)); + if (error) { + kprintf("[virtiofs] inode %lld, open failed\n", inode->nodeid); + return error; + } - if (!error) { - virtiofs_debug("inode %d, opened\n", inode->nodeid); + virtiofs_debug("inode %lld, opened\n", inode->nodeid); - auto *file_data = new virtiofs_file_data(); - file_data->file_handle = out_args->fh; - fp->f_data = file_data; + auto* f_data = new (std::nothrow) virtiofs_file_data; + if (!f_data) { + return ENOMEM; } + f_data->file_handle = out_args->fh; + // TODO OPT: Consult and possibly act upon out_args->open_flags + file_setdata(fp, f_data); - delete input_args; - delete out_args; - - return error; + return 0; } -static int virtiofs_close(struct vnode *vnode, struct file *fp) +static int virtiofs_close(struct vnode* vnode, struct file* fp) { - struct virtiofs_inode *inode = (struct virtiofs_inode *) vnode->v_data; - - auto *input_args = new (std::nothrow) fuse_release_in(); - auto *file_data = reinterpret_cast<virtiofs_file_data*>(fp->f_data); - input_args->fh = file_data->file_handle; + auto* inode = static_cast<virtiofs_inode*>(vnode->v_data); - auto *strategy = reinterpret_cast<fuse_strategy*>(vnode->v_mount->m_data); - auto error = fuse_req_send_and_receive_reply(strategy, FUSE_RELEASE, inode->nodeid, - input_args, sizeof(*input_args), nullptr, 0); - - if (!error) { - fp->f_data = nullptr; - delete file_data; - virtiofs_debug("inode %d, closed\n", inode->nodeid); + std::unique_ptr<fuse_release_in> in_args { + new (std::nothrow) fuse_release_in()}; + if (!in_args) { + return ENOMEM; + } + auto* f_data = static_cast<virtiofs_file_data*>(file_data(fp)); + in_args->fh = f_data->file_handle; + in_args->flags = OPEN_FLAGS; // need to be same as in FUSE_OPEN + + auto* strategy = static_cast<fuse_strategy*>(vnode->v_mount->m_data); + auto error = fuse_req_send_and_receive_reply(strategy, FUSE_RELEASE, + inode->nodeid, in_args.get(), sizeof(*in_args), nullptr, 0); + if (error) { + kprintf("[virtiofs] inode %lld, close failed\n", inode->nodeid); + return error; } - //TODO: Investigate if we should send FUSE_FORGET once all handles to the file closed on our side + file_setdata(fp, nullptr); + delete f_data; + virtiofs_debug("inode %lld, closed\n", inode->nodeid); - delete input_args; + // TODO: Investigate if we should send FUSE_FORGET once all handles to the + // file closed on our side - return error; + return 0; } -static int virtiofs_readlink(struct vnode *vnode, struct uio *uio) +static int virtiofs_readlink(struct vnode* vnode, struct uio* uio) { - struct virtiofs_inode *inode = (struct virtiofs_inode *) vnode->v_data; - - auto *link_path = new (std::nothrow) char[PATH_MAX]; + auto* inode = static_cast<virtiofs_inode*>(vnode->v_data); - auto *strategy = reinterpret_cast<fuse_strategy*>(vnode->v_mount->m_data); - int error = fuse_req_send_and_receive_reply(strategy, FUSE_READLINK, inode->nodeid, - nullptr, 0, link_path, PATH_MAX); - - int ret = 0; - if (!error) { - virtiofs_debug("inode %d, read symlink [%s]\n", inode->nodeid, link_path); - ret = uiomove(link_path, strlen(link_path), uio); - } else { - kprintf("[virtiofs] Error reading data\n"); - ret = error; + std::unique_ptr<char[]> link_path {new (std::nothrow) char[PATH_MAX]}; + if (!link_path) { + return ENOMEM; } - delete link_path; + auto* strategy = static_cast<fuse_strategy*>(vnode->v_mount->m_data); + auto error = fuse_req_send_and_receive_reply(strategy, FUSE_READLINK, + inode->nodeid, nullptr, 0, link_path.get(), PATH_MAX); + if (error) { + kprintf("[virtiofs] inode %lld, readlink failed\n", inode->nodeid); + return error; + } - return ret; + virtiofs_debug("inode %lld, read symlink [%s]\n", inode->nodeid, + link_path.get()); + return uiomove(link_path.get(), strlen(link_path.get()), uio); } -//TODO: Optimize it to reduce number of exits to host (each fuse_req_send_and_receive_reply()) -// by reading eagerly "ahead/around" just like ROFS does and caching it -static int virtiofs_read(struct vnode *vnode, struct file *fp, struct uio *uio, int ioflag) +// TODO: Optimize it to reduce number of exits to host (each +// fuse_req_send_and_receive_reply()) by reading eagerly "ahead/around" just +// like ROFS does and caching it +static int virtiofs_read(struct vnode* vnode, struct file* fp, struct uio* uio, + int ioflag) { - struct virtiofs_inode *inode = (struct virtiofs_inode *) vnode->v_data; + auto* inode = static_cast<virtiofs_inode*>(vnode->v_data); - VERIFY_READ_INPUT_ARGUMENTS() + // Can't read directories + if (vnode->v_type == VDIR) { + return EISDIR; + } + // Can't read anything but reg + if (vnode->v_type != VREG) { + return EINVAL; + } + // Can't start reading before the first byte + if (uio->uio_offset < 0) { + return EINVAL; + } + // Need to read at least 1 byte + if (uio->uio_resid == 0) { + return 0; + } + // Can't read after the end of the file + if (uio->uio_offset >= vnode->v_size) { + return 0; + } // Total read amount is what they requested, or what is left - uint64_t read_amt = std::min<uint64_t>(inode->attr.size - uio->uio_offset, uio->uio_resid); - void *buf = malloc(read_amt); - - auto *input_args = new (std::nothrow) fuse_read_in(); - auto *file_data = reinterpret_cast<virtiofs_file_data*>(fp->f_data); - input_args->fh = file_data->file_handle; - input_args->offset = uio->uio_offset; - input_args->size = read_amt; - input_args->flags = ioflag; - input_args->lock_owner = 0; - - virtiofs_debug("inode %d, reading %d bytes at offset %d\n", inode->nodeid, read_amt, uio->uio_offset); - - auto *strategy = reinterpret_cast<fuse_strategy*>(vnode->v_mount->m_data); - auto error = fuse_req_send_and_receive_reply(strategy, FUSE_READ, inode->nodeid, - input_args, sizeof(*input_args), buf, read_amt); - - int ret = 0; - if (!error) { - ret = uiomove(buf, read_amt, uio); - } else { - kprintf("[virtiofs] Error reading data\n"); - ret = error; + auto read_amt = std::min<uint64_t>(uio->uio_resid, + inode->attr.size - uio->uio_offset); + std::unique_ptr<u8[]> buf {new (std::nothrow) u8[read_amt]}; + std::unique_ptr<fuse_read_in> in_args {new (std::nothrow) fuse_read_in()}; + if (!buf || !in_args) { + return ENOMEM; + } + auto* f_data = static_cast<virtiofs_file_data*>(file_data(fp)); + in_args->fh = f_data->file_handle; + in_args->offset = uio->uio_offset; + in_args->size = read_amt; + in_args->flags = ioflag; + + virtiofs_debug("inode %lld, reading %lld bytes at offset %lld\n", + inode->nodeid, read_amt, uio->uio_offset); + + auto* strategy = static_cast<fuse_strategy*>(vnode->v_mount->m_data); + auto error = fuse_req_send_and_receive_reply(strategy, FUSE_READ, + inode->nodeid, in_args.get(), sizeof(*in_args), buf.get(), read_amt); + if (error) { + kprintf("[virtiofs] inode %lld, read failed\n", inode->nodeid); + return error; } - free(buf); - free(input_args); - - return ret; + return uiomove(buf.get(), read_amt, uio); } -// -static int virtiofs_readdir(struct vnode *vnode, struct file *fp, struct dirent *dir) + +static int virtiofs_readdir(struct vnode* vnode, struct file* fp, + struct dirent* dir) { - //TODO Implement + // TODO: Implement return EPERM; } -static int virtiofs_getattr(struct vnode *vnode, struct vattr *attr) +static int virtiofs_getattr(struct vnode* vnode, struct vattr* attr) { - struct virtiofs_inode *inode = (struct virtiofs_inode *) vnode->v_data; + auto* inode = static_cast<virtiofs_inode*>(vnode->v_data); - attr->va_mode = 0555; //Is it really correct? + // TODO: Call FUSE_GETATTR? But figure out if fuse_getattr_in.fh is + // necessary (look at the flags) + attr->va_mode = 0555; // TODO: Is it really correct? if (S_ISDIR(inode->attr.mode)) { attr->va_type = VDIR; @@ -277,10 +304,11 @@ struct vnops virtiofs_vnops = { virtiofs_getattr, /* getattr */ virtiofs_setattr, /* setattr - returns error when called */ virtiofs_inactive, /* inactive */ - virtiofs_truncate, /* truncate - returns error when called*/ - virtiofs_link, /* link - returns error when called*/ - virtiofs_arc, /* arc */ //TODO: Implement to allow memory re-use when mapping files, investigate using virtio-fs DAX - virtiofs_fallocate, /* fallocate - returns error when called*/ + virtiofs_truncate, /* truncate - returns error when called */ + virtiofs_link, /* link - returns error when called */ + virtiofs_arc, /* arc */ //TODO: Implement to allow memory re-use when + // mapping files, investigate using virtio-fs DAX + virtiofs_fallocate, /* fallocate - returns error when called */ virtiofs_readlink, /* read link */ - virtiofs_symlink /* symbolic link - returns error when called*/ + virtiofs_symlink /* symbolic link - returns error when called */ }; -- 2.26.1 -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/VI1PR03MB438375635D92107C6567FFA8A6D40%40VI1PR03MB4383.eurprd03.prod.outlook.com.
