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.

Reply via email to