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 = { |
