@@ -4,11 +4,12 @@
* compatible drivers/servers. */
#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
-#define MAX_TAG_LEN 8
struct virtio_9p_config {
- /* tag name for the mount point */
- __u8 tag[MAX_TAG_LEN];
+ /* length of the tag name */
+ __u16 tag_len;
+ /* non-NULL terminated tag name */
+ __u8 tag[0];
} __attribute__((packed));
#endif /* _LINUX_VIRTIO_9P_H */
@@ -78,8 +78,11 @@ struct virtio_chan {
/* Scatterlist: can be too big for stack. */
struct scatterlist sg[VIRTQUEUE_NUM];
- /* tag name to identify a mount */
- __u8 tag[MAX_TAG_LEN];
+ int tag_len;
+ /*
+ * tag name to identify a mount Non-null terminated
+ */
+ char *tag;
struct list_head chan_list;
};
@@ -227,7 +230,8 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
static int p9_virtio_probe(struct virtio_device *vdev)
{
- __u8 tag[MAX_TAG_LEN];
+ __u16 tag_len;
+ char *tag;
int err;
struct virtio_chan *chan;
@@ -252,9 +256,17 @@ static int p9_virtio_probe(struct virtio_device *vdev)
sg_init_table(chan->sg, VIRTQUEUE_NUM);
chan->inuse = false;
+ vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag_len),
+ &tag_len, sizeof(tag_len));
+ tag = kmalloc(tag_len, GFP_KERNEL);
+ if (!tag) {
+ err = -ENOMEM;
+ goto out_free_vq;
+ }
vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag),
- tag, sizeof(tag));
- memcpy(chan->tag, tag, MAX_TAG_LEN);
+ tag, tag_len);
+ chan->tag = tag;
+ chan->tag_len = tag_len;
mutex_lock(&virtio_9p_lock);
list_add_tail(&chan->chan_list, &virtio_chan_list);
mutex_unlock(&virtio_9p_lock);
@@ -291,7 +303,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
mutex_lock(&virtio_9p_lock);
list_for_each_entry(chan, &virtio_chan_list, chan_list) {
- if (!strncmp(devname, chan->tag, MAX_TAG_LEN)) {
+ if (!strncmp(devname, chan->tag, chan->tag_len)) {
if (!chan->inuse) {
chan->inuse = true;
found = 1;
@@ -330,6 +342,7 @@ static void p9_virtio_remove(struct virtio_device *vdev)
mutex_lock(&virtio_9p_lock);
list_del(&chan->chan_list);
mutex_unlock(&virtio_9p_lock);
+ kfree(chan->tag);
kfree(chan);
}