[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v2 1/6] lib/ramfs: initial import from OSv
Reviewed-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> > On 8. Feb 2019, at 15:31, Yuri Volchkov <yuri.volchkov@xxxxxxxxx> wrote: > > git tag: v0.52.0 > commit: 00299190414e4c7c5b0f2d74cd11763dac34e5b9 > > Signed-off-by: Yuri Volchkov <yuri.volchkov@xxxxxxxxx> > --- > lib/ramfs/ramfs.h | 68 ++++ > lib/ramfs/ramfs_vfsops.c | 90 ++++++ > lib/ramfs/ramfs_vnops.c | 669 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 827 insertions(+) > create mode 100644 lib/ramfs/ramfs.h > create mode 100644 lib/ramfs/ramfs_vfsops.c > create mode 100644 lib/ramfs/ramfs_vnops.c > > diff --git a/lib/ramfs/ramfs.h b/lib/ramfs/ramfs.h > new file mode 100644 > index 00000000..88ccbe72 > --- /dev/null > +++ b/lib/ramfs/ramfs.h > @@ -0,0 +1,68 @@ > +/* > + * Copyright (c) 2006-2007, Kohsuke Ohtani > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. Neither the name of the author nor the names of any co-contributors > + * may be used to endorse or promote products derived from this software > + * without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + */ > + > +#ifndef _RAMFS_H > +#define _RAMFS_H > + > +#include <osv/prex.h> > + > +/* #define DEBUG_RAMFS 1 */ > + > +#ifdef DEBUG_RAMFS > +#define DPRINTF(a) dprintf a > +#else > +#define DPRINTF(a) do {} while (0) > +#endif > + > +#define ASSERT(e) assert(e) > + > +/* > + * File/directory node for RAMFS > + */ > +struct ramfs_node { > + struct ramfs_node *rn_next; /* next node in the same directory */ > + struct ramfs_node *rn_child; /* first child node */ > + int rn_type; /* file or directory */ > + char *rn_name; /* name (null-terminated) */ > + size_t rn_namelen; /* length of name not including terminator */ > + size_t rn_size; /* file size */ > + char *rn_buf; /* buffer to the file data */ > + size_t rn_bufsize; /* allocated buffer size */ > + struct timespec rn_ctime; > + struct timespec rn_atime; > + struct timespec rn_mtime; > + int rn_mode; > + bool rn_owns_buf; > +}; > + > +struct ramfs_node *ramfs_allocate_node(const char *name, int type); > + > +void ramfs_free_node(struct ramfs_node *node); > + > +#endif /* !_RAMFS_H */ > diff --git a/lib/ramfs/ramfs_vfsops.c b/lib/ramfs/ramfs_vfsops.c > new file mode 100644 > index 00000000..72fe7edb > --- /dev/null > +++ b/lib/ramfs/ramfs_vfsops.c > @@ -0,0 +1,90 @@ > +/* > + * Copyright (c) 2006-2007, Kohsuke Ohtani > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. Neither the name of the author nor the names of any co-contributors > + * may be used to endorse or promote products derived from this software > + * without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + */ > + > +#include <errno.h> > + > +#include <osv/vnode.h> > +#include <osv/mount.h> > +#include <osv/dentry.h> > + > +#include "ramfs.h" > + > +extern struct vnops ramfs_vnops; > + > +static int ramfs_mount(struct mount *mp, const char *dev, int flags, const > void *data); > + > +static int ramfs_unmount(struct mount *mp, int flags); > + > +#define ramfs_sync ((vfsop_sync_t)vfs_nullop) > +#define ramfs_vget ((vfsop_vget_t)vfs_nullop) > +#define ramfs_statfs ((vfsop_statfs_t)vfs_nullop) > + > +/* > + * File system operations > + */ > +struct vfsops ramfs_vfsops = { > + ramfs_mount, /* mount */ > + ramfs_unmount, /* unmount */ > + ramfs_sync, /* sync */ > + ramfs_vget, /* vget */ > + ramfs_statfs, /* statfs */ > + &ramfs_vnops, /* vnops */ > +}; > + > +/* > + * Mount a file system. > + */ > +static int > +ramfs_mount(struct mount *mp, const char *dev, int flags, const void *data) > +{ > + struct ramfs_node *np; > + > + DPRINTF(("ramfs_mount: dev=%s\n", dev)); > + > + /* Create a root node */ > + np = ramfs_allocate_node("/", VDIR); > + if (np == NULL) > + return ENOMEM; > + mp->m_root->d_vnode->v_data = np; > + return 0; > +} > + > +/* > + * Unmount a file system. > + * > + * NOTE: Currently, we don't support unmounting of the RAMFS. This is > + * because we have to deallocate all nodes included in all sub > + * directories, and it requires more work... > + */ > +static int > +ramfs_unmount(struct mount *mp, int flags) > +{ > + release_mp_dentries(mp); > + return 0; > +} > diff --git a/lib/ramfs/ramfs_vnops.c b/lib/ramfs/ramfs_vnops.c > new file mode 100644 > index 00000000..9291a4ec > --- /dev/null > +++ b/lib/ramfs/ramfs_vnops.c > @@ -0,0 +1,669 @@ > +/* > + * Copyright (c) 2006-2007, Kohsuke Ohtani > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. Neither the name of the author nor the names of any co-contributors > + * may be used to endorse or promote products derived from this software > + * without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + */ > + > +/* > + * rmafs_vnops.c - vnode operations for RAM file system. > + */ > + > +#include <sys/stat.h> > +#include <dirent.h> > +#include <sys/param.h> > + > +#include <errno.h> > +#include <string.h> > +#include <stdlib.h> > +#include <fcntl.h> > + > +#include <osv/prex.h> > +#include <osv/vnode.h> > +#include <osv/file.h> > +#include <osv/mount.h> > +#include <osv/vnode_attr.h> > + > +#include "ramfs.h" > + > +static mutex_t ramfs_lock = MUTEX_INITIALIZER; > +static uint64_t inode_count = 1; /* inode 0 is reserved to root */ > + > +static void > +set_times_to_now(struct timespec *time1, struct timespec *time2 = nullptr, > struct timespec *time3 = nullptr) > +{ > + struct timespec now; > + clock_gettime(CLOCK_REALTIME, &now); > + if (time1) { > + memcpy(time1, &now, sizeof(struct timespec)); > + } > + if (time2) { > + memcpy(time2, &now, sizeof(struct timespec)); > + } > + if (time3) { > + memcpy(time3, &now, sizeof(struct timespec)); > + } > +} > + > +struct ramfs_node * > +ramfs_allocate_node(const char *name, int type) > +{ > + struct ramfs_node *np; > + > + np = (ramfs_node *) malloc(sizeof(struct ramfs_node)); > + if (np == NULL) > + return NULL; > + memset(np, 0, sizeof(struct ramfs_node)); > + > + np->rn_namelen = strlen(name); > + np->rn_name = (char *) malloc(np->rn_namelen + 1); > + if (np->rn_name == NULL) { > + free(np); > + return NULL; > + } > + strlcpy(np->rn_name, name, np->rn_namelen + 1); > + np->rn_type = type; > + > + if (type == VDIR) > + np->rn_mode = S_IFDIR|0777; > + else if (type == VLNK) > + np->rn_mode = S_IFLNK|0777; > + else > + np->rn_mode = S_IFREG|0777; > + > + set_times_to_now(&(np->rn_ctime), &(np->rn_atime), &(np->rn_mtime)); > + np->rn_owns_buf = true; > + > + return np; > +} > + > +void > +ramfs_free_node(struct ramfs_node *np) > +{ > + if (np->rn_buf != NULL && np->rn_owns_buf) > + free(np->rn_buf); > + > + free(np->rn_name); > + free(np); > +} > + > +static struct ramfs_node * > +ramfs_add_node(struct ramfs_node *dnp, char *name, int type) > +{ > + struct ramfs_node *np, *prev; > + > + np = ramfs_allocate_node(name, type); > + if (np == NULL) > + return NULL; > + > + mutex_lock(&ramfs_lock); > + > + /* Link to the directory list */ > + if (dnp->rn_child == NULL) { > + dnp->rn_child = np; > + } else { > + prev = dnp->rn_child; > + while (prev->rn_next != NULL) > + prev = prev->rn_next; > + prev->rn_next = np; > + } > + > + set_times_to_now(&(dnp->rn_mtime), &(dnp->rn_ctime)); > + > + mutex_unlock(&ramfs_lock); > + return np; > +} > + > +static int > +ramfs_remove_node(struct ramfs_node *dnp, struct ramfs_node *np) > +{ > + struct ramfs_node *prev; > + > + if (dnp->rn_child == NULL) > + return EBUSY; > + > + mutex_lock(&ramfs_lock); > + > + /* Unlink from the directory list */ > + if (dnp->rn_child == np) { > + dnp->rn_child = np->rn_next; > + } else { > + for (prev = dnp->rn_child; prev->rn_next != np; > + prev = prev->rn_next) { > + if (prev->rn_next == NULL) { > + mutex_unlock(&ramfs_lock); > + return ENOENT; > + } > + } > + prev->rn_next = np->rn_next; > + } > + ramfs_free_node(np); > + > + set_times_to_now(&(dnp->rn_mtime), &(dnp->rn_ctime)); > + > + mutex_unlock(&ramfs_lock); > + return 0; > +} > + > +static int > +ramfs_rename_node(struct ramfs_node *np, char *name) > +{ > + size_t len; > + char *tmp; > + > + len = strlen(name); > + if (len > NAME_MAX) { > + return ENAMETOOLONG; > + } > + if (len <= np->rn_namelen) { > + /* Reuse current name buffer */ > + strlcpy(np->rn_name, name, np->rn_namelen + 1); > + } else { > + /* Expand name buffer */ > + tmp = (char *) malloc(len + 1); > + if (tmp == NULL) > + return ENOMEM; > + strlcpy(tmp, name, len + 1); > + free(np->rn_name); > + np->rn_name = tmp; > + } > + np->rn_namelen = len; > + set_times_to_now(&(np->rn_ctime)); > + return 0; > +} > + > +static int > +ramfs_lookup(struct vnode *dvp, char *name, struct vnode **vpp) > +{ > + struct ramfs_node *np, *dnp; > + struct vnode *vp; > + size_t len; > + int found; > + > + *vpp = NULL; > + > + if (*name == '\0') > + return ENOENT; > + > + mutex_lock(&ramfs_lock); > + > + len = strlen(name); > + dnp = (ramfs_node *) dvp->v_data; > + found = 0; > + for (np = dnp->rn_child; np != NULL; np = np->rn_next) { > + if (np->rn_namelen == len && > + memcmp(name, np->rn_name, len) == 0) { > + found = 1; > + break; > + } > + } > + if (found == 0) { > + mutex_unlock(&ramfs_lock); > + return ENOENT; > + } > + if (vget(dvp->v_mount, inode_count++, &vp)) { > + /* found in cache */ > + *vpp = vp; > + mutex_unlock(&ramfs_lock); > + return 0; > + } > + if (!vp) { > + mutex_unlock(&ramfs_lock); > + return ENOMEM; > + } > + vp->v_data = np; > + vp->v_mode = ALLPERMS; > + vp->v_type = np->rn_type; > + vp->v_size = np->rn_size; > + > + mutex_unlock(&ramfs_lock); > + > + *vpp = vp; > + > + return 0; > +} > + > +static int > +ramfs_mkdir(struct vnode *dvp, char *name, mode_t mode) > +{ > + struct ramfs_node *np; > + > + DPRINTF(("mkdir %s\n", name)); > + if (strlen(name) > NAME_MAX) { > + return ENAMETOOLONG; > + } > + > + if (!S_ISDIR(mode)) > + return EINVAL; > + > + np = (ramfs_node *) ramfs_add_node((ramfs_node *) dvp->v_data, name, > VDIR); > + if (np == NULL) > + return ENOMEM; > + np->rn_size = 0; > + > + return 0; > +} > + > +static int > +ramfs_symlink(struct vnode *dvp, char *name, char *link) > +{ > + if (strlen(name) > NAME_MAX) { > + return ENAMETOOLONG; > + } > + auto np = ramfs_add_node((ramfs_node *) dvp->v_data, name, VLNK); > + if (np == NULL) > + return ENOMEM; > + // Save the link target without the final null, as readlink() wants it. > + size_t len = strlen(link); > + np->rn_buf = strndup(link, len); > + np->rn_bufsize = np->rn_size = len; > + > + return 0; > +} > + > +static int > +ramfs_readlink(struct vnode *vp, struct uio *uio) > +{ > + struct ramfs_node *np = (ramfs_node *) vp->v_data; > + size_t len; > + > + if (vp->v_type != VLNK) { > + return EINVAL; > + } > + if (uio->uio_offset < 0) { > + return EINVAL; > + } > + if (uio->uio_resid == 0) { > + return 0; > + } > + if (uio->uio_offset >= (off_t) vp->v_size) > + return 0; > + if (vp->v_size - uio->uio_offset < uio->uio_resid) > + len = vp->v_size - uio->uio_offset; > + else > + len = uio->uio_resid; > + > + set_times_to_now( &(np->rn_atime)); > + return uiomove(np->rn_buf + uio->uio_offset, len, uio); > +} > + > +/* Remove a directory */ > +static int > +ramfs_rmdir(struct vnode *dvp, struct vnode *vp, char *name) > +{ > + return ramfs_remove_node((ramfs_node *) dvp->v_data, (ramfs_node *) > vp->v_data); > +} > + > +/* Remove a file */ > +static int > +ramfs_remove(struct vnode *dvp, struct vnode *vp, char *name) > +{ > + DPRINTF(("remove %s in %s\n", name, dvp->v_path)); > + return ramfs_remove_node((ramfs_node *) dvp->v_data, (ramfs_node *) > vp->v_data); > +} > + > +/* Truncate file */ > +static int > +ramfs_truncate(struct vnode *vp, off_t length) > +{ > + struct ramfs_node *np; > + void *new_buf; > + size_t new_size; > + > + DPRINTF(("truncate %s length=%d\n", vp->v_path, length)); > + np = (ramfs_node *) vp->v_data; > + > + if (length == 0) { > + if (np->rn_buf != NULL) { > + if(np->rn_owns_buf) > + free(np->rn_buf); > + np->rn_buf = NULL; > + np->rn_bufsize = 0; > + } > + } else if (size_t(length) > np->rn_bufsize) { > + // XXX: this could use a page level allocator > + new_size = round_page(length); > + new_buf = malloc(new_size); > + if (!new_buf) > + return EIO; > + if (np->rn_size != 0) { > + memcpy(new_buf, np->rn_buf, vp->v_size); > + if(np->rn_owns_buf) > + free(np->rn_buf); > + } > + np->rn_buf = (char *) new_buf; > + np->rn_bufsize = new_size; > + np->rn_owns_buf = true; > + } > + np->rn_size = length; > + vp->v_size = length; > + set_times_to_now(&(np->rn_mtime), &(np->rn_ctime)); > + return 0; > +} > + > +/* > + * Create empty file. > + */ > +static int > +ramfs_create(struct vnode *dvp, char *name, mode_t mode) > +{ > + struct ramfs_node *np; > + > + if (strlen(name) > NAME_MAX) { > + return ENAMETOOLONG; > + } > + > + DPRINTF(("create %s in %s\n", name, dvp->v_path)); > + if (!S_ISREG(mode)) > + return EINVAL; > + > + np = ramfs_add_node((ramfs_node *) dvp->v_data, name, VREG); > + if (np == NULL) > + return ENOMEM; > + return 0; > +} > + > +static int > +ramfs_read(struct vnode *vp, struct file *fp, struct uio *uio, int ioflag) > +{ > + struct ramfs_node *np = (ramfs_node *) vp->v_data; > + size_t len; > + > + if (vp->v_type == VDIR) { > + return EISDIR; > + } > + if (vp->v_type != VREG) { > + return EINVAL; > + } > + if (uio->uio_offset < 0) { > + return EINVAL; > + } > + if (uio->uio_resid == 0) { > + return 0; > + } > + > + if (uio->uio_offset >= (off_t) vp->v_size) > + return 0; > + > + if (vp->v_size - uio->uio_offset < uio->uio_resid) > + len = vp->v_size - uio->uio_offset; > + else > + len = uio->uio_resid; > + > + set_times_to_now(&(np->rn_atime)); > + > + return uiomove(np->rn_buf + uio->uio_offset, len, uio); > +} > + > +int > +ramfs_set_file_data(struct vnode *vp, const void *data, size_t size) > +{ > + struct ramfs_node *np = (ramfs_node *) vp->v_data; > + > + if (vp->v_type == VDIR) { > + return EISDIR; > + } > + if (vp->v_type != VREG) { > + return EINVAL; > + } > + if (np->rn_buf) { > + return EINVAL; > + } > + > + np->rn_buf = (char *) data; > + np->rn_bufsize = size; > + np->rn_size = size; > + vp->v_size = size; > + np->rn_owns_buf = false; > + > + return 0; > +} > + > +static int > +ramfs_write(struct vnode *vp, struct uio *uio, int ioflag) > +{ > + struct ramfs_node *np = (ramfs_node *) vp->v_data; > + > + if (vp->v_type == VDIR) { > + return EISDIR; > + } > + if (vp->v_type != VREG) { > + return EINVAL; > + } > + if (uio->uio_offset < 0) { > + return EINVAL; > + } > + if (uio->uio_offset >= LONG_MAX) { > + return EFBIG; > + } > + if (uio->uio_resid == 0) { > + return 0; > + } > + > + if (ioflag & IO_APPEND) > + uio->uio_offset = np->rn_size; > + > + if (size_t(uio->uio_offset + uio->uio_resid) > (size_t) vp->v_size) { > + /* Expand the file size before writing to it */ > + off_t end_pos = uio->uio_offset + uio->uio_resid; > + if (end_pos > (off_t) np->rn_bufsize) { > + // XXX: this could use a page level allocator > + size_t new_size = round_page(end_pos); > + void *new_buf = malloc(new_size); > + if (!new_buf) > + return EIO; > + if (np->rn_size != 0) { > + memcpy(new_buf, np->rn_buf, vp->v_size); > + if(np->rn_owns_buf) > + free(np->rn_buf); > + } > + np->rn_buf = (char *) new_buf; > + np->rn_bufsize = new_size; > + } > + np->rn_size = end_pos; > + vp->v_size = end_pos; > + np->rn_owns_buf = true; > + } > + > + set_times_to_now(&(np->rn_mtime), &(np->rn_ctime)); > + return uiomove(np->rn_buf + uio->uio_offset, uio->uio_resid, uio); > +} > + > +static int > +ramfs_rename(struct vnode *dvp1, struct vnode *vp1, char *name1, > + struct vnode *dvp2, struct vnode *vp2, char *name2) > +{ > + struct ramfs_node *np, *old_np; > + int error; > + > + if (vp2) { > + /* Remove destination file, first */ > + error = ramfs_remove_node((ramfs_node *) dvp2->v_data, (ramfs_node > *) vp2->v_data); > + if (error) > + return error; > + } > + /* Same directory ? */ > + if (dvp1 == dvp2) { > + /* Change the name of existing file */ > + error = ramfs_rename_node((ramfs_node *) vp1->v_data, name2); > + if (error) > + return error; > + } else { > + /* Create new file or directory */ > + old_np = (ramfs_node *) vp1->v_data; > + np = ramfs_add_node((ramfs_node *) dvp2->v_data, name2, > old_np->rn_type); > + if (np == NULL) > + return ENOMEM; > + > + if (old_np->rn_buf) { > + /* Copy file data */ > + np->rn_buf = old_np->rn_buf; > + np->rn_size = old_np->rn_size; > + np->rn_bufsize = old_np->rn_bufsize; > + old_np->rn_buf = NULL; > + } > + /* Remove source file */ > + ramfs_remove_node((ramfs_node *) dvp1->v_data, (ramfs_node *) > vp1->v_data); > + } > + return 0; > +} > + > +/* > + * @vp: vnode of the directory. > + */ > +static int > +ramfs_readdir(struct vnode *vp, struct file *fp, struct dirent *dir) > +{ > + struct ramfs_node *np, *dnp; > + int i; > + > + mutex_lock(&ramfs_lock); > + > + set_times_to_now(&(((ramfs_node *) vp->v_data)->rn_atime)); > + > + if (fp->f_offset == 0) { > + dir->d_type = DT_DIR; > + strlcpy((char *) &dir->d_name, ".", sizeof(dir->d_name)); > + } else if (fp->f_offset == 1) { > + dir->d_type = DT_DIR; > + strlcpy((char *) &dir->d_name, "..", sizeof(dir->d_name)); > + } else { > + dnp = (ramfs_node *) vp->v_data; > + np = dnp->rn_child; > + if (np == NULL) { > + mutex_unlock(&ramfs_lock); > + return ENOENT; > + } > + > + for (i = 0; i != (fp->f_offset - 2); i++) { > + np = np->rn_next; > + if (np == NULL) { > + mutex_unlock(&ramfs_lock); > + return ENOENT; > + } > + } > + if (np->rn_type == VDIR) > + dir->d_type = DT_DIR; > + else if (np->rn_type == VLNK) > + dir->d_type = DT_LNK; > + else > + dir->d_type = DT_REG; > + strlcpy((char *) &dir->d_name, np->rn_name, > + sizeof(dir->d_name)); > + } > + dir->d_fileno = fp->f_offset; > +// dir->d_namelen = strlen(dir->d_name); > + > + fp->f_offset++; > + > + mutex_unlock(&ramfs_lock); > + return 0; > +} > + > +int > +ramfs_init(void) > +{ > + return 0; > +} > + > +static int > +ramfs_getattr(struct vnode *vnode, struct vattr *attr) > +{ > + attr->va_nodeid = vnode->v_ino; > + attr->va_size = vnode->v_size; > + > + struct ramfs_node *np = (ramfs_node *) vnode->v_data; > + attr->va_type = (vtype) np->rn_type; > + > + memcpy(&(attr->va_atime), &(np->rn_atime), sizeof(struct timespec)); > + memcpy(&(attr->va_ctime), &(np->rn_ctime), sizeof(struct timespec)); > + memcpy(&(attr->va_mtime), &(np->rn_mtime), sizeof(struct timespec)); > + > + attr->va_mode = np->rn_mode; > + > + return 0; > +} > + > +static int > +ramfs_setattr(struct vnode *vnode, struct vattr *attr) { > + struct ramfs_node *np = (ramfs_node *) vnode->v_data; > + > + if (attr->va_mask & AT_ATIME) { > + memcpy(&(np->rn_atime), &(attr->va_atime), sizeof(struct timespec)); > + } > + > + if (attr->va_mask & AT_CTIME) { > + memcpy(&(np->rn_ctime), &(attr->va_ctime), sizeof(struct timespec)); > + } > + > + if (attr->va_mask & AT_MTIME) { > + memcpy(&(np->rn_mtime), &(attr->va_mtime), sizeof(struct timespec)); > + } > + > + if (attr->va_mask & AT_MODE) { > + np->rn_mode = attr->va_mode; > + } > + > + return 0; > +} > + > +#define ramfs_open ((vnop_open_t)vop_nullop) > +#define ramfs_close ((vnop_close_t)vop_nullop) > +#define ramfs_seek ((vnop_seek_t)vop_nullop) > +#define ramfs_ioctl ((vnop_ioctl_t)vop_einval) > +#define ramfs_fsync ((vnop_fsync_t)vop_nullop) > +#define ramfs_inactive ((vnop_inactive_t)vop_nullop) > +#define ramfs_link ((vnop_link_t)vop_eperm) > +#define ramfs_fallocate ((vnop_fallocate_t)vop_nullop) > + > +/* > + * vnode operations > + */ > +struct vnops ramfs_vnops = { > + ramfs_open, /* open */ > + ramfs_close, /* close */ > + ramfs_read, /* read */ > + ramfs_write, /* write */ > + ramfs_seek, /* seek */ > + ramfs_ioctl, /* ioctl */ > + ramfs_fsync, /* fsync */ > + ramfs_readdir, /* readdir */ > + ramfs_lookup, /* lookup */ > + ramfs_create, /* create */ > + ramfs_remove, /* remove */ > + ramfs_rename, /* remame */ > + ramfs_mkdir, /* mkdir */ > + ramfs_rmdir, /* rmdir */ > + ramfs_getattr, /* getattr */ > + ramfs_setattr, /* setattr */ > + ramfs_inactive, /* inactive */ > + ramfs_truncate, /* truncate */ > + ramfs_link, /* link */ > + (vnop_cache_t) nullptr, /* arc */ > + ramfs_fallocate, /* fallocate */ > + ramfs_readlink, /* read link */ > + ramfs_symlink, /* symbolic link */ > +}; > + > -- > 2.19.2 > > > _______________________________________________ > Minios-devel mailing list > Minios-devel@xxxxxxxxxxxxxxxxxxxx > https://lists.xenproject.org/mailman/listinfo/minios-devel _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |