Commit 62ec6073 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'aneesh/for-upstream-5' into staging

parents 0bce98df 5f542225
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -308,7 +308,7 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o
9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o
9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o
9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-handle.o

hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
$(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS)
+36 −18
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <sys/stat.h>
#include <sys/uio.h>
#include <sys/vfs.h>

#define SM_LOCAL_MODE_BITS    0600
#define SM_LOCAL_DIR_MODE_BITS    0700

@@ -49,51 +50,68 @@ typedef struct FsCred

struct xattr_operations;

/* FsContext flag values */
#define PATHNAME_FSCONTEXT 0x1

typedef struct FsContext
{
    int flags;
    char *fs_root;
    SecModel fs_sm;
    uid_t uid;
    struct xattr_operations **xops;
    /* fs driver specific data */
    void *private;
} FsContext;

typedef struct V9fsPath {
    int16_t size;
    char *data;
} V9fsPath;

void cred_init(FsCred *);

typedef struct FileOperations
{
    int (*lstat)(FsContext *, const char *, struct stat *);
    ssize_t (*readlink)(FsContext *, const char *, char *, size_t);
    int (*chmod)(FsContext *, const char *, FsCred *);
    int (*chown)(FsContext *, const char *, FsCred *);
    int (*mknod)(FsContext *, const char *, FsCred *);
    int (*utimensat)(FsContext *, const char *, const struct timespec *);
    int (*init)(struct FsContext *);
    int (*lstat)(FsContext *, V9fsPath *, struct stat *);
    ssize_t (*readlink)(FsContext *, V9fsPath *, char *, size_t);
    int (*chmod)(FsContext *, V9fsPath *, FsCred *);
    int (*chown)(FsContext *, V9fsPath *, FsCred *);
    int (*mknod)(FsContext *, V9fsPath *, const char *, FsCred *);
    int (*utimensat)(FsContext *, V9fsPath *, const struct timespec *);
    int (*remove)(FsContext *, const char *);
    int (*symlink)(FsContext *, const char *, const char *, FsCred *);
    int (*link)(FsContext *, const char *, const char *);
    int (*symlink)(FsContext *, const char *, V9fsPath *,
                   const char *, FsCred *);
    int (*link)(FsContext *, V9fsPath *, V9fsPath *, const char *);
    int (*setuid)(FsContext *, uid_t);
    int (*close)(FsContext *, int);
    int (*closedir)(FsContext *, DIR *);
    DIR *(*opendir)(FsContext *, const char *);
    int (*open)(FsContext *, const char *, int);
    int (*open2)(FsContext *, const char *, int, FsCred *);
    DIR *(*opendir)(FsContext *, V9fsPath *);
    int (*open)(FsContext *, V9fsPath *, int);
    int (*open2)(FsContext *, V9fsPath *, const char *, int, FsCred *);
    void (*rewinddir)(FsContext *, DIR *);
    off_t (*telldir)(FsContext *, DIR *);
    int (*readdir_r)(FsContext *, DIR *, struct dirent *, struct dirent **);
    void (*seekdir)(FsContext *, DIR *, off_t);
    ssize_t (*preadv)(FsContext *, int, const struct iovec *, int, off_t);
    ssize_t (*pwritev)(FsContext *, int, const struct iovec *, int, off_t);
    int (*mkdir)(FsContext *, const char *, FsCred *);
    int (*mkdir)(FsContext *, V9fsPath *, const char *, FsCred *);
    int (*fstat)(FsContext *, int, struct stat *);
    int (*rename)(FsContext *, const char *, const char *);
    int (*truncate)(FsContext *, const char *, off_t);
    int (*truncate)(FsContext *, V9fsPath *, off_t);
    int (*fsync)(FsContext *, int, int);
    int (*statfs)(FsContext *s, const char *path, struct statfs *stbuf);
    ssize_t (*lgetxattr)(FsContext *, const char *,
    int (*statfs)(FsContext *s, V9fsPath *path, struct statfs *stbuf);
    ssize_t (*lgetxattr)(FsContext *, V9fsPath *,
                         const char *, void *, size_t);
    ssize_t (*llistxattr)(FsContext *, const char *, void *, size_t);
    int (*lsetxattr)(FsContext *, const char *,
    ssize_t (*llistxattr)(FsContext *, V9fsPath *, void *, size_t);
    int (*lsetxattr)(FsContext *, V9fsPath *,
                     const char *, void *, size_t, int);
    int (*lremovexattr)(FsContext *, const char *, const char *);
    int (*lremovexattr)(FsContext *, V9fsPath *, const char *);
    int (*name_to_path)(FsContext *, V9fsPath *, const char *, V9fsPath *);
    int (*renameat)(FsContext *ctx, V9fsPath *olddir, const char *old_name,
                    V9fsPath *newdir, const char *new_name);
    int (*unlinkat)(FsContext *ctx, V9fsPath *dir, const char *name, int flags);
    void *opaque;
} FileOperations;

+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ static QTAILQ_HEAD(FsTypeEntry_head, FsTypeListEntry) fstype_entries =

static FsTypeTable FsTypes[] = {
    { .name = "local", .ops = &local_ops},
    { .name = "handle", .ops = &handle_ops},
};

int qemu_fsdev_add(QemuOpts *opts)
+1 −0
Original line number Diff line number Diff line
@@ -52,4 +52,5 @@ typedef struct FsTypeListEntry {
int qemu_fsdev_add(QemuOpts *opts);
FsTypeEntry *get_fsdev_fsentry(char *id);
extern FileOperations local_ops;
extern FileOperations handle_ops;
#endif
+54 −10
Original line number Diff line number Diff line
@@ -17,11 +17,15 @@
#include "qemu-coroutine.h"
#include "virtio-9p-coth.h"

int v9fs_co_readdir_r(V9fsState *s, V9fsFidState *fidp, struct dirent *dent,
int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
                      struct dirent **result)
{
    int err;
    V9fsState *s = pdu->s;

    if (v9fs_request_cancelled(pdu)) {
        return -EINTR;
    }
    v9fs_co_run_in_worker(
        {
            errno = 0;
@@ -35,10 +39,14 @@ int v9fs_co_readdir_r(V9fsState *s, V9fsFidState *fidp, struct dirent *dent,
    return err;
}

off_t v9fs_co_telldir(V9fsState *s, V9fsFidState *fidp)
off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp)
{
    off_t err;
    V9fsState *s = pdu->s;

    if (v9fs_request_cancelled(pdu)) {
        return -EINTR;
    }
    v9fs_co_run_in_worker(
        {
            err = s->ops->telldir(&s->ctx, fidp->fs.dir);
@@ -49,67 +57,103 @@ off_t v9fs_co_telldir(V9fsState *s, V9fsFidState *fidp)
    return err;
}

void v9fs_co_seekdir(V9fsState *s, V9fsFidState *fidp, off_t offset)
void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset)
{
    V9fsState *s = pdu->s;
    if (v9fs_request_cancelled(pdu)) {
        return;
    }
    v9fs_co_run_in_worker(
        {
            s->ops->seekdir(&s->ctx, fidp->fs.dir, offset);
        });
}

void v9fs_co_rewinddir(V9fsState *s, V9fsFidState *fidp)
void v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp)
{
    V9fsState *s = pdu->s;
    if (v9fs_request_cancelled(pdu)) {
        return;
    }
    v9fs_co_run_in_worker(
        {
            s->ops->rewinddir(&s->ctx, fidp->fs.dir);
        });
}

int v9fs_co_mkdir(V9fsState *s, char *name, mode_t mode, uid_t uid, gid_t gid)
int v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name,
                  mode_t mode, uid_t uid, gid_t gid, struct stat *stbuf)
{
    int err;
    FsCred cred;
    V9fsPath path;
    V9fsState *s = pdu->s;

    if (v9fs_request_cancelled(pdu)) {
        return -EINTR;;
    }
    cred_init(&cred);
    cred.fc_mode = mode;
    cred.fc_uid = uid;
    cred.fc_gid = gid;
    v9fs_path_read_lock(s);
    v9fs_co_run_in_worker(
        {
            err = s->ops->mkdir(&s->ctx, name, &cred);
            err = s->ops->mkdir(&s->ctx, &fidp->path, name->data,  &cred);
            if (err < 0) {
                err = -errno;
            } else {
                v9fs_path_init(&path);
                err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
                if (!err) {
                    err = s->ops->lstat(&s->ctx, &path, stbuf);
                    if (err < 0) {
                        err = -errno;
                    }
                }
                v9fs_path_free(&path);
            }
        });
    v9fs_path_unlock(s);
    return err;
}

int v9fs_co_opendir(V9fsState *s, V9fsFidState *fidp)
int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
{
    int err;
    V9fsState *s = pdu->s;

    if (v9fs_request_cancelled(pdu)) {
        return -EINTR;;
    }
    v9fs_path_read_lock(s);
    v9fs_co_run_in_worker(
        {
            fidp->fs.dir = s->ops->opendir(&s->ctx, fidp->path.data);
            fidp->fs.dir = s->ops->opendir(&s->ctx, &fidp->path);
            if (!fidp->fs.dir) {
                err = -errno;
            } else {
                err = 0;
            }
        });
    v9fs_path_unlock(s);
    if (!err) {
        total_open_fd++;
        if (total_open_fd > open_fd_hw) {
            v9fs_reclaim_fd(s);
            v9fs_reclaim_fd(pdu);
        }
    }
    return err;
}

int v9fs_co_closedir(V9fsState *s, DIR *dir)
int v9fs_co_closedir(V9fsPDU *pdu, DIR *dir)
{
    int err;
    V9fsState *s = pdu->s;

    if (v9fs_request_cancelled(pdu)) {
        return -EINTR;;
    }
    v9fs_co_run_in_worker(
        {
            err = s->ops->closedir(&s->ctx, dir);
Loading