[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v3 1/6] lib/ramfs: initial import from OSv
git tag: v0.52.0 commit: 00299190414e4c7c5b0f2d74cd11763dac34e5b9 Signed-off-by: Yuri Volchkov <yuri.volchkov@xxxxxxxxx> Reviewed-by: Simon Kuenzer <simon.kuenzer@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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |