/*
 * Virtio 9p synthetic file system support
 *
 * Copyright IBM, Corp. 2011
 *
 * Authors:
 *  Malahal Naineni <malahal@us.ibm.com>
 *  Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 *
 */

#include "hw/virtio.h"
#include "virtio-9p.h"
#include "virtio-9p-xattr.h"
#include "fsdev/qemu-fsdev.h"
#include "virtio-9p-synth.h"

#include <sys/stat.h>

/* Root node for synth file system */
V9fsSynthNode v9fs_synth_root = {
    .name = "/",
    .actual_attr = {
        .mode = 0555 | S_IFDIR,
        .nlink = 1,
    },
    .attr = &v9fs_synth_root.actual_attr,
};

static QemuMutex  v9fs_synth_mutex;
static int v9fs_synth_node_count;
/* set to 1 when the synth fs is ready */
static int v9fs_synth_fs;

static V9fsSynthNode *v9fs_add_dir_node(V9fsSynthNode *parent, int mode,
                                        const char *name,
                                        V9fsSynthNodeAttr *attr, int inode)
{
    V9fsSynthNode *node;

    /* Add directory type and remove write bits */
    mode = ((mode & 0777) | S_IFDIR) & ~(S_IWUSR | S_IWGRP | S_IWOTH);
    node = g_malloc0(sizeof(V9fsSynthNode));
    if (attr) {
        /* We are adding .. or . entries */
        node->attr = attr;
        node->attr->nlink++;
    } else {
        node->attr = &node->actual_attr;
        node->attr->inode = inode;
        node->attr->nlink = 1;
        /* We don't allow write to directories */
        node->attr->mode   = mode;
        node->attr->write = NULL;
        node->attr->read  = NULL;
    }
    node->private = node;
    pstrcpy(node->name, sizeof(node->name), name);
    QLIST_INSERT_HEAD_RCU(&parent->child, node, sibling);
    return node;
}

int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,
                          const char *name, V9fsSynthNode **result)
{
    int ret;
    V9fsSynthNode *node, *tmp;

    if (!v9fs_synth_fs) {
        return EAGAIN;
    }
    if (!name || (strlen(name) >= NAME_MAX)) {
        return EINVAL;
    }
    if (!parent) {
        parent = &v9fs_synth_root;
    }
    qemu_mutex_lock(&v9fs_synth_mutex);
    QLIST_FOREACH(tmp, &parent->child, sibling) {
        if (!strcmp(tmp->name, name)) {
            ret = EEXIST;
            goto err_out;
        }
    }
    /* Add the name */
    node = v9fs_add_dir_node(parent, mode, name, NULL, v9fs_synth_node_count++);
    v9fs_add_dir_node(node, parent->attr->mode, "..",
                      parent->attr, parent->attr->inode);
    v9fs_add_dir_node(node, node->attr->mode, ".",
                      node->attr, node->attr->inode);
    *result = node;
    ret = 0;
err_out:
    qemu_mutex_unlock(&v9fs_synth_mutex);
    return ret;
}

int qemu_v9fs_synth_add_file(V9fsSynthNode *parent, int mode,
                             const char *name, v9fs_synth_read read,
                             v9fs_synth_write write, void *arg)
{
    int ret;
    V9fsSynthNode *node, *tmp;

    if (!v9fs_synth_fs) {
        return EAGAIN;
    }
    if (!name || (strlen(name) >= NAME_MAX)) {
        return EINVAL;
    }
    if (!parent) {
        parent = &v9fs_synth_root;
    }

    qemu_mutex_lock(&v9fs_synth_mutex);
    QLIST_FOREACH(tmp, &parent->child, sibling) {
        if (!strcmp(tmp->name, name)) {
            ret = EEXIST;
            goto err_out;
        }
    }
    /* Add file type and remove write bits */
    mode = ((mode & 0777) | S_IFREG);
    node = g_malloc0(sizeof(V9fsSynthNode));
    node->attr         = &node->actual_attr;
    node->attr->inode  = v9fs_synth_node_count++;
    node->attr->nlink  = 1;
    node->attr->read   = read;
    node->attr->write  = write;
    node->attr->mode   = mode;
    node->private      = arg;
    pstrcpy(node->name, sizeof(node->name), name);
    QLIST_INSERT_HEAD_RCU(&parent->child, node, sibling);
    ret = 0;
err_out:
    qemu_mutex_unlock(&v9fs_synth_mutex);
    return ret;
}

static void v9fs_synth_fill_statbuf(V9fsSynthNode *node, struct stat *stbuf)
{
    stbuf->st_dev = 0;
    stbuf->st_ino = node->attr->inode;
    stbuf->st_mode = node->attr->mode;
    stbuf->st_nlink = node->attr->nlink;
    stbuf->st_uid = 0;
    stbuf->st_gid = 0;
    stbuf->st_rdev = 0;
    stbuf->st_size = 0;
    stbuf->st_blksize = 0;
    stbuf->st_blocks = 0;
    stbuf->st_atime = 0;
    stbuf->st_mtime = 0;
    stbuf->st_ctime = 0;
}

static int v9fs_synth_lstat(FsContext *fs_ctx,
                            V9fsPath *fs_path, struct stat *stbuf)
{
    V9fsSynthNode *node = *(V9fsSynthNode **)fs_path->data;

    v9fs_synth_fill_statbuf(node, stbuf);
    return 0;
}

static int v9fs_synth_fstat(FsContext *fs_ctx, int fid_type,
                            V9fsFidOpenState *fs, struct stat *stbuf)
{
    V9fsSynthOpenState *synth_open = fs->private;
    v9fs_synth_fill_statbuf(synth_open->node, stbuf);
    return 0;
}

static int v9fs_synth_opendir(FsContext *ctx,
                             V9fsPath *fs_path, V9fsFidOpenState *fs)
{
    V9fsSynthOpenState *synth_open;
    V9fsSynthNode *node = *(V9fsSynthNode **)fs_path->data;

    synth_open = g_malloc(sizeof(*synth_open));
    synth_open->node = node;
    node->open_count++;
    fs->private = synth_open;
    return 0;
}

static int v9fs_synth_closedir(FsContext *ctx, V9fsFidOpenState *fs)
{
    V9fsSynthOpenState *synth_open = fs->private;
    V9fsSynthNode *node = synth_open->node;

    node->open_count--;
    g_free(synth_open);
    fs->private = NULL;
    return 0;
}

static off_t v9fs_synth_telldir(FsContext *ctx, V9fsFidOpenState *fs)
{
    V9fsSynthOpenState *synth_open = fs->private;
    return synth_open->offset;
}

static void v9fs_synth_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
{
    V9fsSynthOpenState *synth_open = fs->private;
    synth_open->offset = off;
}

static void v9fs_synth_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
{
    v9fs_synth_seekdir(ctx, fs, 0);
}

static void v9fs_synth_direntry(V9fsSynthNode *node,
                                struct dirent *entry, off_t off)
{
    strcpy(entry->d_name, node->name);
    entry->d_ino = node->attr->inode;
    entry->d_off = off + 1;
}

static int v9fs_synth_get_dentry(V9fsSynthNode *dir, struct dirent *entry,
                                 struct dirent **result, off_t off)
{
    int i = 0;
    V9fsSynthNode *node;

    rcu_read_lock();
    QLIST_FOREACH(node, &dir->child, sibling) {
        /* This is the off child of the directory */
        if (i == off) {
            break;
        }
        i++;
    }
    rcu_read_unlock();
    if (!node) {
        /* end of directory */
        *result = NULL;
        return 0;
    }
    v9fs_synth_direntry(node, entry, off);
    *result = entry;
    return 0;
}

static int v9fs_synth_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
                                struct dirent *entry, struct dirent **result)
{
    int ret;
    V9fsSynthOpenState *synth_open = fs->private;
    V9fsSynthNode *node = synth_open->node;
    ret = v9fs_synth_get_dentry(node, entry, result, synth_open->offset);
    if (!ret && *result != NULL) {
        synth_open->offset++;
    }
    return ret;
}

static int v9fs_synth_open(FsContext *ctx, V9fsPath *fs_path,
                           int flags, V9fsFidOpenState *fs)
{
    V9fsSynthOpenState *synth_open;
    V9fsSynthNode *node = *(V9fsSynthNode **)fs_path->data;

    synth_open = g_malloc(sizeof(*synth_open));
    synth_open->node = node;
    node->open_count++;
    fs->private = synth_open;
    return 0;
}

static int v9fs_synth_open2(FsContext *fs_ctx, V9fsPath *dir_path,
                            const char *name, int flags,
                            FsCred *credp, V9fsFidOpenState *fs)
{
    errno = ENOSYS;
    return -1;
}

static int v9fs_synth_close(FsContext *ctx, V9fsFidOpenState *fs)
{
    V9fsSynthOpenState *synth_open = fs->private;
    V9fsSynthNode *node = synth_open->node;

    node->open_count--;
    g_free(synth_open);
    fs->private = NULL;
    return 0;
}

static ssize_t v9fs_synth_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
                                  const struct iovec *iov,
                                  int iovcnt, off_t offset)
{
    int i, count = 0, wcount;
    V9fsSynthOpenState *synth_open = fs->private;
    V9fsSynthNode *node = synth_open->node;
    if (!node->attr->write) {
        errno = EPERM;
        return -1;
    }
    for (i = 0; i < iovcnt; i++) {
        wcount = node->attr->write(iov[i].iov_base, iov[i].iov_len,
                                   offset, node->private);
        offset += wcount;
        count  += wcount;
        /* If we wrote less than requested. we are done */
        if (wcount < iov[i].iov_len) {
            break;
        }
    }
    return count;
}

static ssize_t v9fs_synth_preadv(FsContext *ctx, V9fsFidOpenState *fs,
                                 const struct iovec *iov,
                                 int iovcnt, off_t offset)
{
    int i, count = 0, rcount;
    V9fsSynthOpenState *synth_open = fs->private;
    V9fsSynthNode *node = synth_open->node;
    if (!node->attr->read) {
        errno = EPERM;
        return -1;
    }
    for (i = 0; i < iovcnt; i++) {
        rcount = node->attr->read(iov[i].iov_base, iov[i].iov_len,
                                  offset, node->private);
        offset += rcount;
        count  += rcount;
        /* If we read less than requested. we are done */
        if (rcount < iov[i].iov_len) {
            break;
        }
    }
    return count;
}

static int v9fs_synth_truncate(FsContext *ctx, V9fsPath *path, off_t offset)
{
    errno = ENOSYS;
    return -1;
}

static int v9fs_synth_chmod(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
{
    errno = EPERM;
    return -1;
}

static int v9fs_synth_mknod(FsContext *fs_ctx, V9fsPath *path,
                       const char *buf, FsCred *credp)
{
    errno = EPERM;
    return -1;
}

static int v9fs_synth_mkdir(FsContext *fs_ctx, V9fsPath *path,
                       const char *buf, FsCred *credp)
{
    errno = EPERM;
    return -1;
}

static ssize_t v9fs_synth_readlink(FsContext *fs_ctx, V9fsPath *path,
                                   char *buf, size_t bufsz)
{
    errno = ENOSYS;
    return -1;
}

static int v9fs_synth_symlink(FsContext *fs_ctx, const char *oldpath,
                              V9fsPath *newpath, const char *buf, FsCred *credp)
{
    errno = EPERM;
    return -1;
}

static int v9fs_synth_link(FsContext *fs_ctx, V9fsPath *oldpath,
                           V9fsPath *newpath, const char *buf)
{
    errno = EPERM;
    return -1;
}

static int v9fs_synth_rename(FsContext *ctx, const char *oldpath,
                             const char *newpath)
{
    errno = EPERM;
    return -1;
}

static int v9fs_synth_chown(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
{
    errno = EPERM;
    return -1;
}

static int v9fs_synth_utimensat(FsContext *fs_ctx, V9fsPath *path,
                                const struct timespec *buf)
{
    errno = EPERM;
    return 0;
}

static int v9fs_synth_remove(FsContext *ctx, const char *path)
{
    errno = EPERM;
    return -1;
}

static int v9fs_synth_fsync(FsContext *ctx, int fid_type,
                            V9fsFidOpenState *fs, int datasync)
{
    errno = ENOSYS;
    return 0;
}

static int v9fs_synth_statfs(FsContext *s, V9fsPath *fs_path,
                             struct statfs *stbuf)
{
    stbuf->f_type = 0xABCD;
    stbuf->f_bsize = 512;
    stbuf->f_blocks = 0;
    stbuf->f_files = v9fs_synth_node_count;
    stbuf->f_namelen = NAME_MAX;
    return 0;
}

static ssize_t v9fs_synth_lgetxattr(FsContext *ctx, V9fsPath *path,
                                    const char *name, void *value, size_t size)
{
    errno = ENOTSUP;
    return -1;
}

static ssize_t v9fs_synth_llistxattr(FsContext *ctx, V9fsPath *path,
                                     void *value, size_t size)
{
    errno = ENOTSUP;
    return -1;
}

static int v9fs_synth_lsetxattr(FsContext *ctx, V9fsPath *path,
                                const char *name, void *value,
                                size_t size, int flags)
{
    errno = ENOTSUP;
    return -1;
}

static int v9fs_synth_lremovexattr(FsContext *ctx,
                                   V9fsPath *path, const char *name)
{
    errno = ENOTSUP;
    return -1;
}

static int v9fs_synth_name_to_path(FsContext *ctx, V9fsPath *dir_path,
                                   const char *name, V9fsPath *target)
{
    V9fsSynthNode *node;
    V9fsSynthNode *dir_node;

    /* "." and ".." are not allowed */
    if (!strcmp(name, ".") || !strcmp(name, "..")) {
        errno = EINVAL;
        return -1;

    }
    if (!dir_path) {
        dir_node = &v9fs_synth_root;
    } else {
        dir_node = *(V9fsSynthNode **)dir_path->data;
    }
    if (!strcmp(name, "/")) {
        node = dir_node;
        goto out;
    }
    /* search for the name in the childern */
    rcu_read_lock();
    QLIST_FOREACH(node, &dir_node->child, sibling) {
        if (!strcmp(node->name, name)) {
            break;
        }
    }
    rcu_read_unlock();

    if (!node) {
        errno = ENOENT;
        return -1;
    }
out:
    /* Copy the node pointer to fid */
    target->data = g_malloc(sizeof(void *));
    memcpy(target->data, &node, sizeof(void *));
    target->size = sizeof(void *);
    return 0;
}

static int v9fs_synth_renameat(FsContext *ctx, V9fsPath *olddir,
                               const char *old_name, V9fsPath *newdir,
                               const char *new_name)
{
    errno = EPERM;
    return -1;
}

static int v9fs_synth_unlinkat(FsContext *ctx, V9fsPath *dir,
                               const char *name, int flags)
{
    errno = EPERM;
    return -1;
}

static int v9fs_synth_init(FsContext *ctx)
{
    QLIST_INIT(&v9fs_synth_root.child);
    qemu_mutex_init(&v9fs_synth_mutex);

    /* Add "." and ".." entries for root */
    v9fs_add_dir_node(&v9fs_synth_root, v9fs_synth_root.attr->mode,
                      "..", v9fs_synth_root.attr, v9fs_synth_root.attr->inode);
    v9fs_add_dir_node(&v9fs_synth_root, v9fs_synth_root.attr->mode,
                      ".", v9fs_synth_root.attr, v9fs_synth_root.attr->inode);

    /* Mark the subsystem is ready for use */
    v9fs_synth_fs = 1;
    return 0;
}

FileOperations synth_ops = {
    .init         = v9fs_synth_init,
    .lstat        = v9fs_synth_lstat,
    .readlink     = v9fs_synth_readlink,
    .close        = v9fs_synth_close,
    .closedir     = v9fs_synth_closedir,
    .open         = v9fs_synth_open,
    .opendir      = v9fs_synth_opendir,
    .rewinddir    = v9fs_synth_rewinddir,
    .telldir      = v9fs_synth_telldir,
    .readdir_r    = v9fs_synth_readdir_r,
    .seekdir      = v9fs_synth_seekdir,
    .preadv       = v9fs_synth_preadv,
    .pwritev      = v9fs_synth_pwritev,
    .chmod        = v9fs_synth_chmod,
    .mknod        = v9fs_synth_mknod,
    .mkdir        = v9fs_synth_mkdir,
    .fstat        = v9fs_synth_fstat,
    .open2        = v9fs_synth_open2,
    .symlink      = v9fs_synth_symlink,
    .link         = v9fs_synth_link,
    .truncate     = v9fs_synth_truncate,
    .rename       = v9fs_synth_rename,
    .chown        = v9fs_synth_chown,
    .utimensat    = v9fs_synth_utimensat,
    .remove       = v9fs_synth_remove,
    .fsync        = v9fs_synth_fsync,
    .statfs       = v9fs_synth_statfs,
    .lgetxattr    = v9fs_synth_lgetxattr,
    .llistxattr   = v9fs_synth_llistxattr,
    .lsetxattr    = v9fs_synth_lsetxattr,
    .lremovexattr = v9fs_synth_lremovexattr,
    .name_to_path = v9fs_synth_name_to_path,
    .renameat     = v9fs_synth_renameat,
    .unlinkat     = v9fs_synth_unlinkat,
};
