diff options
-rw-r--r-- | include/linux/virtio_9p.h | 12 | ||||
-rw-r--r-- | net/9p/trans_virtio.c | 44 |
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 @@ | |||
5 | #include <linux/virtio_ids.h> | 5 | #include <linux/virtio_ids.h> |
6 | #include <linux/virtio_config.h> | 6 | #include <linux/virtio_config.h> |
7 | 7 | ||
8 | /* The feature bitmap for virtio 9P */ | ||
9 | |||
10 | /* The mount point is specified in a config variable */ | ||
11 | #define VIRTIO_9P_MOUNT_TAG 0 | ||
12 | |||
13 | struct virtio_9p_config { | ||
14 | /* length of the tag name */ | ||
15 | __u16 tag_len; | ||
16 | /* non-NULL terminated tag name */ | ||
17 | __u8 tag[0]; | ||
18 | } __attribute__((packed)); | ||
19 | |||
8 | #endif /* _LINUX_VIRTIO_9P_H */ | 20 | #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 { | |||
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 | ||
225 | static int p9_virtio_probe(struct virtio_device *vdev) | 231 | static 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 | ||
361 | static unsigned int features[] = { | ||
362 | VIRTIO_9P_MOUNT_TAG, | ||
363 | }; | ||
364 | |||
335 | /* The standard "struct lguest_driver": */ | 365 | /* The standard "struct lguest_driver": */ |
336 | static struct virtio_driver p9_virtio_drv = { | 366 | static 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 | ||
344 | static struct p9_trans_module p9_virtio_trans = { | 376 | static struct p9_trans_module p9_virtio_trans = { |