aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p/trans_virtio.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/9p/trans_virtio.c')
-rw-r--r--net/9p/trans_virtio.c44
1 files changed, 38 insertions, 6 deletions
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 {
78 /* Scatterlist: can be too big for stack. */ 78 /* Scatterlist: can be too big for stack. */
79 struct scatterlist sg[VIRTQUEUE_NUM]; 79 struct scatterlist sg[VIRTQUEUE_NUM];
80 80
81 int tag_len;
82 /*
83 * tag name to identify a mount Non-null terminated
84 */
85 char *tag;
86
81 struct list_head chan_list; 87 struct list_head chan_list;
82}; 88};
83 89
@@ -224,6 +230,8 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
224 230
225static int p9_virtio_probe(struct virtio_device *vdev) 231static int p9_virtio_probe(struct virtio_device *vdev)
226{ 232{
233 __u16 tag_len;
234 char *tag;
227 int err; 235 int err;
228 struct virtio_chan *chan; 236 struct virtio_chan *chan;
229 237
@@ -248,6 +256,23 @@ static int p9_virtio_probe(struct virtio_device *vdev)
248 sg_init_table(chan->sg, VIRTQUEUE_NUM); 256 sg_init_table(chan->sg, VIRTQUEUE_NUM);
249 257
250 chan->inuse = false; 258 chan->inuse = false;
259 if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) {
260 vdev->config->get(vdev,
261 offsetof(struct virtio_9p_config, tag_len),
262 &tag_len, sizeof(tag_len));
263 } else {
264 err = -EINVAL;
265 goto out_free_vq;
266 }
267 tag = kmalloc(tag_len, GFP_KERNEL);
268 if (!tag) {
269 err = -ENOMEM;
270 goto out_free_vq;
271 }
272 vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag),
273 tag, tag_len);
274 chan->tag = tag;
275 chan->tag_len = tag_len;
251 mutex_lock(&virtio_9p_lock); 276 mutex_lock(&virtio_9p_lock);
252 list_add_tail(&chan->chan_list, &virtio_chan_list); 277 list_add_tail(&chan->chan_list, &virtio_chan_list);
253 mutex_unlock(&virtio_9p_lock); 278 mutex_unlock(&virtio_9p_lock);
@@ -284,7 +309,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
284 309
285 mutex_lock(&virtio_9p_lock); 310 mutex_lock(&virtio_9p_lock);
286 list_for_each_entry(chan, &virtio_chan_list, chan_list) { 311 list_for_each_entry(chan, &virtio_chan_list, chan_list) {
287 if (!strcmp(devname, dev_name(&chan->vdev->dev))) { 312 if (!strncmp(devname, chan->tag, chan->tag_len)) {
288 if (!chan->inuse) { 313 if (!chan->inuse) {
289 chan->inuse = true; 314 chan->inuse = true;
290 found = 1; 315 found = 1;
@@ -323,6 +348,7 @@ static void p9_virtio_remove(struct virtio_device *vdev)
323 mutex_lock(&virtio_9p_lock); 348 mutex_lock(&virtio_9p_lock);
324 list_del(&chan->chan_list); 349 list_del(&chan->chan_list);
325 mutex_unlock(&virtio_9p_lock); 350 mutex_unlock(&virtio_9p_lock);
351 kfree(chan->tag);
326 kfree(chan); 352 kfree(chan);
327 353
328} 354}
@@ -332,13 +358,19 @@ static struct virtio_device_id id_table[] = {
332 { 0 }, 358 { 0 },
333}; 359};
334 360
361static unsigned int features[] = {
362 VIRTIO_9P_MOUNT_TAG,
363};
364
335/* The standard "struct lguest_driver": */ 365/* The standard "struct lguest_driver": */
336static struct virtio_driver p9_virtio_drv = { 366static struct virtio_driver p9_virtio_drv = {
337 .driver.name = KBUILD_MODNAME, 367 .feature_table = features,
338 .driver.owner = THIS_MODULE, 368 .feature_table_size = ARRAY_SIZE(features),
339 .id_table = id_table, 369 .driver.name = KBUILD_MODNAME,
340 .probe = p9_virtio_probe, 370 .driver.owner = THIS_MODULE,
341 .remove = p9_virtio_remove, 371 .id_table = id_table,
372 .probe = p9_virtio_probe,
373 .remove = p9_virtio_remove,
342}; 374};
343 375
344static struct p9_trans_module p9_virtio_trans = { 376static struct p9_trans_module p9_virtio_trans = {