summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2010-03-06 07:44:14 +0300
committerEric Van Hensbergen <ericvh@gmail.com>2010-03-13 17:57:28 +0300
commit97ee9b0257402f4731b55dfea42f24d26d793ddf (patch)
tree191e6b08fd882862ede97925a0584f408f6e6e1c
parentdaf9fe2ee9a203c4fc555cfe5c5f3d9f660e743c (diff)
downloadlinux-97ee9b0257402f4731b55dfea42f24d26d793ddf.tar.xz
net/9p: Use the tag name in the config space for identifying mount point
This patch use the tag name in the config space to identify the mount device. The the virtio device name depend on the enumeration order of the device and may not remain the same across multiple boots So we use the tag name which is set via qemu option to uniquely identify the mount device Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
-rw-r--r--include/linux/virtio_9p.h12
-rw-r--r--net/9p/trans_virtio.c44
2 files changed, 50 insertions, 6 deletions
diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h
index 332275080083..5cf11765146b 100644
--- a/include/linux/virtio_9p.h
+++ b/include/linux/virtio_9p.h
@@ -5,4 +5,16 @@
#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
+/* The feature bitmap for virtio 9P */
+
+/* The mount point is specified in a config variable */
+#define VIRTIO_9P_MOUNT_TAG 0
+
+struct virtio_9p_config {
+ /* length of the tag name */
+ __u16 tag_len;
+ /* non-NULL terminated tag name */
+ __u8 tag[0];
+} __attribute__((packed));
+
#endif /* _LINUX_VIRTIO_9P_H */
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 0aaed4819379..026775ad391a 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -78,6 +78,12 @@ struct virtio_chan {
/* Scatterlist: can be too big for stack. */
struct scatterlist sg[VIRTQUEUE_NUM];
+ int tag_len;
+ /*
+ * tag name to identify a mount Non-null terminated
+ */
+ char *tag;
+
struct list_head chan_list;
};
@@ -224,6 +230,8 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
static int p9_virtio_probe(struct virtio_device *vdev)
{
+ __u16 tag_len;
+ char *tag;
int err;
struct virtio_chan *chan;
@@ -248,6 +256,23 @@ static int p9_virtio_probe(struct virtio_device *vdev)
sg_init_table(chan->sg, VIRTQUEUE_NUM);
chan->inuse = false;
+ if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) {
+ vdev->config->get(vdev,
+ offsetof(struct virtio_9p_config, tag_len),
+ &tag_len, sizeof(tag_len));
+ } else {
+ err = -EINVAL;
+ goto out_free_vq;
+ }
+ 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, 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);
@@ -284,7 +309,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 (!strcmp(devname, dev_name(&chan->vdev->dev))) {
+ if (!strncmp(devname, chan->tag, chan->tag_len)) {
if (!chan->inuse) {
chan->inuse = true;
found = 1;
@@ -323,6 +348,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);
}
@@ -332,13 +358,19 @@ static struct virtio_device_id id_table[] = {
{ 0 },
};
+static unsigned int features[] = {
+ VIRTIO_9P_MOUNT_TAG,
+};
+
/* The standard "struct lguest_driver": */
static struct virtio_driver p9_virtio_drv = {
- .driver.name = KBUILD_MODNAME,
- .driver.owner = THIS_MODULE,
- .id_table = id_table,
- .probe = p9_virtio_probe,
- .remove = p9_virtio_remove,
+ .feature_table = features,
+ .feature_table_size = ARRAY_SIZE(features),
+ .driver.name = KBUILD_MODNAME,
+ .driver.owner = THIS_MODULE,
+ .id_table = id_table,
+ .probe = p9_virtio_probe,
+ .remove = p9_virtio_remove,
};
static struct p9_trans_module p9_virtio_trans = {