Skip to content

Commit

Permalink
9pfs: introduce V9fsVirtioState
Browse files Browse the repository at this point in the history
V9fsState now only contains generic fields. Introduce V9fsVirtioState
for virtio transport.  Change virtio-pci and virtio-ccw to use
V9fsVirtioState.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
  • Loading branch information
Wei Liu authored and kvaneesh committed Jan 12, 2016
1 parent 2a0c56a commit 00588a0
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 40 deletions.
11 changes: 8 additions & 3 deletions hw/9pfs/9p.c
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
6 changes: 1 addition & 5 deletions hw/9pfs/9p.h
Expand Up @@ -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;
};


Expand Down Expand Up @@ -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;
/*
Expand Down
78 changes: 49 additions & 29 deletions hw/9pfs/virtio-9p-device.c
Expand Up @@ -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];

BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0);
len = virtqueue_pop(vq, elem);
if (!len) {
pdu_free(pdu);
break;
}

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);

Expand All @@ -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,
Expand All @@ -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);
}

Expand All @@ -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;
Expand All @@ -118,44 +127,55 @@ static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
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(),
};

Expand All @@ -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,
};

Expand Down
12 changes: 11 additions & 1 deletion hw/9pfs/virtio-9p.h
Expand Up @@ -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,
Expand All @@ -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
2 changes: 1 addition & 1 deletion hw/s390x/virtio-ccw.h
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion hw/virtio/virtio-pci.h
Expand Up @@ -242,7 +242,7 @@ struct VirtIONetPCI {

typedef struct V9fsPCIState {
VirtIOPCIProxy parent_obj;
V9fsState vdev;
V9fsVirtioState vdev;
} V9fsPCIState;

#endif
Expand Down

0 comments on commit 00588a0

Please sign in to comment.