Commit 00588a0a authored by Wei Liu's avatar Wei Liu Committed by Aneesh Kumar K.V
Browse files

9pfs: introduce V9fsVirtioState



V9fsState now only contains generic fields. Introduce V9fsVirtioState
for virtio transport.  Change virtio-pci and virtio-ccw to use
V9fsVirtioState.

Signed-off-by: default avatarWei Liu <wei.liu2@citrix.com>
Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
parent 2a0c56aa
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -1585,6 +1585,8 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
    size_t offset = 7;
    int read_count;
    int64_t xattr_len;
    V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
    VirtQueueElement *elem = &v->elems[pdu->idx];

    xattr_len = fidp->fs.xattr.len;
    read_count = xattr_len - off;
@@ -1601,7 +1603,8 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
        return err;
    }
    offset += err;
    err = v9fs_pack(pdu->elem.in_sg, pdu->elem.in_num, offset,

    err = v9fs_pack(elem->in_sg, elem->in_num, offset,
                    ((char *)fidp->fs.xattr.value) + off,
                    read_count);
    if (err < 0) {
@@ -3269,6 +3272,7 @@ void pdu_submit(V9fsPDU *pdu)
/* Returns 0 on success, 1 on failure. */
int v9fs_device_realize_common(V9fsState *s, Error **errp)
{
    V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
    int i, len;
    struct stat stat;
    FsDriverEntry *fse;
@@ -3279,8 +3283,9 @@ int v9fs_device_realize_common(V9fsState *s, Error **errp)
    QLIST_INIT(&s->free_list);
    QLIST_INIT(&s->active_list);
    for (i = 0; i < (MAX_REQ - 1); i++) {
        QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next);
        s->pdus[i].s = s;
        QLIST_INSERT_HEAD(&s->free_list, &v->pdus[i], next);
        v->pdus[i].s = s;
        v->pdus[i].idx = i;
    }

    v9fs_path_init(&path);
+1 −5
Original line number Diff line number Diff line
@@ -131,9 +131,9 @@ struct V9fsPDU
    uint8_t id;
    uint8_t cancelled;
    CoQueue complete;
    VirtQueueElement elem;
    struct V9fsState *s;
    QLIST_ENTRY(V9fsPDU) next;
    uint32_t idx;
};


@@ -205,16 +205,12 @@ struct V9fsFidState

typedef struct V9fsState
{
    VirtIODevice parent_obj;
    VirtQueue *vq;
    V9fsPDU pdus[MAX_REQ];
    QLIST_HEAD(, V9fsPDU) free_list;
    QLIST_HEAD(, V9fsPDU) active_list;
    V9fsFidState *fid_list;
    FileOperations *ops;
    FsContext ctx;
    char *tag;
    size_t config_size;
    enum p9_proto_version proto_version;
    int32_t msize;
    /*
+49 −29
Original line number Diff line number Diff line
@@ -24,33 +24,41 @@
void virtio_9p_push_and_notify(V9fsPDU *pdu)
{
    V9fsState *s = pdu->s;
    V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
    VirtQueueElement *elem = &v->elems[pdu->idx];

    /* push onto queue and notify */
    virtqueue_push(s->vq, &pdu->elem, pdu->size);
    virtqueue_push(v->vq, elem, pdu->size);

    /* FIXME: we should batch these completions */
    virtio_notify(VIRTIO_DEVICE(s), s->vq);
    virtio_notify(VIRTIO_DEVICE(v), v->vq);
}

static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
{
    V9fsState *s = (V9fsState *)vdev;
    V9fsVirtioState *v = (V9fsVirtioState *)vdev;
    V9fsState *s = &v->state;
    V9fsPDU *pdu;
    ssize_t len;

    while ((pdu = pdu_alloc(s)) &&
            (len = virtqueue_pop(vq, &pdu->elem)) != 0) {
    while ((pdu = pdu_alloc(s))) {
        struct {
            uint32_t size_le;
            uint8_t id;
            uint16_t tag_le;
        } QEMU_PACKED out;
        int len;
        VirtQueueElement *elem = &v->elems[pdu->idx];

        len = virtqueue_pop(vq, elem);
        if (!len) {
            pdu_free(pdu);
            break;
        }

        BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0);
        BUG_ON(elem->out_num == 0 || elem->in_num == 0);
        QEMU_BUILD_BUG_ON(sizeof out != 7);

        len = iov_to_buf(pdu->elem.out_sg, pdu->elem.out_num, 0,
        len = iov_to_buf(elem->out_sg, elem->out_num, 0,
                         &out, sizeof out);
        BUG_ON(len != sizeof out);

@@ -62,7 +70,6 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
        qemu_co_queue_init(&pdu->complete);
        pdu_submit(pdu);
    }
    pdu_free(pdu);
}

static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features,
@@ -76,14 +83,15 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
{
    int len;
    struct virtio_9p_config *cfg;
    V9fsState *s = VIRTIO_9P(vdev);
    V9fsVirtioState *v = VIRTIO_9P(vdev);
    V9fsState *s = &v->state;

    len = strlen(s->tag);
    cfg = g_malloc0(sizeof(struct virtio_9p_config) + len);
    virtio_stw_p(vdev, &cfg->tag_len, len);
    /* We don't copy the terminating null to config space */
    memcpy(cfg->tag, s->tag, len);
    memcpy(config, cfg, s->config_size);
    memcpy(config, cfg, v->config_size);
    g_free(cfg);
}

@@ -100,16 +108,17 @@ static int virtio_9p_load(QEMUFile *f, void *opaque, int version_id)
static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    V9fsState *s = VIRTIO_9P(dev);
    V9fsVirtioState *v = VIRTIO_9P(dev);
    V9fsState *s = &v->state;

    if (v9fs_device_realize_common(s, errp)) {
        goto out;
    }

    s->config_size = sizeof(struct virtio_9p_config) + strlen(s->fsconf.tag);
    virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P, s->config_size);
    s->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
    register_savevm(dev, "virtio-9p", -1, 1, virtio_9p_save, virtio_9p_load, s);
    v->config_size = sizeof(struct virtio_9p_config) + strlen(s->fsconf.tag);
    virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P, v->config_size);
    v->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
    register_savevm(dev, "virtio-9p", -1, 1, virtio_9p_save, virtio_9p_load, v);

out:
    return;
@@ -118,44 +127,55 @@ out:
static void virtio_9p_device_unrealize(DeviceState *dev, Error **errp)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    V9fsState *s = VIRTIO_9P(dev);
    V9fsVirtioState *v = VIRTIO_9P(dev);
    V9fsState *s = &v->state;

    virtio_cleanup(vdev);
    unregister_savevm(dev, "virtio-9p", s);
    unregister_savevm(dev, "virtio-9p", v);
    v9fs_device_unrealize_common(s, errp);
}

ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_t offset,
                            const char *fmt, va_list ap)
{
    return v9fs_iov_vmarshal(pdu->elem.in_sg, pdu->elem.in_num,
                             offset, 1, fmt, ap);
    V9fsState *s = pdu->s;
    V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
    VirtQueueElement *elem = &v->elems[pdu->idx];

    return v9fs_iov_vmarshal(elem->in_sg, elem->in_num, offset, 1, fmt, ap);
}

ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, size_t offset,
                              const char *fmt, va_list ap)
{
    return v9fs_iov_vunmarshal(pdu->elem.out_sg, pdu->elem.out_num,
                               offset, 1, fmt, ap);
    V9fsState *s = pdu->s;
    V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
    VirtQueueElement *elem = &v->elems[pdu->idx];

    return v9fs_iov_vunmarshal(elem->out_sg, elem->out_num, offset, 1, fmt, ap);
}

void virtio_init_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov,
                              unsigned int *pniov, bool is_write)
{
    V9fsState *s = pdu->s;
    V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
    VirtQueueElement *elem = &v->elems[pdu->idx];

    if (is_write) {
        *piov = pdu->elem.out_sg;
        *pniov = pdu->elem.out_num;
        *piov = elem->out_sg;
        *pniov = elem->out_num;
    } else {
        *piov = pdu->elem.in_sg;
        *pniov = pdu->elem.in_num;
        *piov = elem->in_sg;
        *pniov = elem->in_num;
    }
}

/* virtio-9p device */

static Property virtio_9p_properties[] = {
    DEFINE_PROP_STRING("mount_tag", V9fsState, fsconf.tag),
    DEFINE_PROP_STRING("fsdev", V9fsState, fsconf.fsdev_id),
    DEFINE_PROP_STRING("mount_tag", V9fsVirtioState, state.fsconf.tag),
    DEFINE_PROP_STRING("fsdev", V9fsVirtioState, state.fsconf.fsdev_id),
    DEFINE_PROP_END_OF_LIST(),
};

@@ -175,7 +195,7 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)
static const TypeInfo virtio_device_info = {
    .name = TYPE_VIRTIO_9P,
    .parent = TYPE_VIRTIO_DEVICE,
    .instance_size = sizeof(V9fsState),
    .instance_size = sizeof(V9fsVirtioState),
    .class_init = virtio_9p_class_init,
};

+11 −1
Original line number Diff line number Diff line
@@ -5,6 +5,16 @@
#include "hw/virtio/virtio.h"
#include "9p.h"

typedef struct V9fsVirtioState
{
    VirtIODevice parent_obj;
    VirtQueue *vq;
    size_t config_size;
    V9fsPDU pdus[MAX_REQ];
    VirtQueueElement elems[MAX_REQ];
    V9fsState state;
} V9fsVirtioState;

extern void virtio_9p_push_and_notify(V9fsPDU *pdu);

ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_t offset,
@@ -16,6 +26,6 @@ void virtio_init_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov,

#define TYPE_VIRTIO_9P "virtio-9p-device"
#define VIRTIO_9P(obj) \
        OBJECT_CHECK(V9fsState, (obj), TYPE_VIRTIO_9P)
        OBJECT_CHECK(V9fsVirtioState, (obj), TYPE_VIRTIO_9P)

#endif
+1 −1
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@ VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch);

typedef struct V9fsCCWState {
    VirtioCcwDevice parent_obj;
    V9fsState vdev;
    V9fsVirtioState vdev;
} V9fsCCWState;

#endif /* CONFIG_VIRTFS */
Loading