diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/9p/client.c | 16 | ||||
| -rw-r--r-- | net/9p/trans_virtio.c | 64 |
2 files changed, 66 insertions, 14 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index bde9f3d38c57..e3e5bf4469ce 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
| @@ -60,7 +60,7 @@ static const match_table_t tokens = { | |||
| 60 | 60 | ||
| 61 | inline int p9_is_proto_dotl(struct p9_client *clnt) | 61 | inline int p9_is_proto_dotl(struct p9_client *clnt) |
| 62 | { | 62 | { |
| 63 | return (clnt->proto_version == p9_proto_2010L); | 63 | return (clnt->proto_version == p9_proto_2000L); |
| 64 | } | 64 | } |
| 65 | EXPORT_SYMBOL(p9_is_proto_dotl); | 65 | EXPORT_SYMBOL(p9_is_proto_dotl); |
| 66 | 66 | ||
| @@ -80,9 +80,9 @@ static unsigned char get_protocol_version(const substring_t *name) | |||
| 80 | } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) { | 80 | } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) { |
| 81 | version = p9_proto_2000u; | 81 | version = p9_proto_2000u; |
| 82 | P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n"); | 82 | P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n"); |
| 83 | } else if (!strncmp("9p2010.L", name->from, name->to-name->from)) { | 83 | } else if (!strncmp("9p2000.L", name->from, name->to-name->from)) { |
| 84 | version = p9_proto_2010L; | 84 | version = p9_proto_2000L; |
| 85 | P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2010.L\n"); | 85 | P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n"); |
| 86 | } else { | 86 | } else { |
| 87 | P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ", | 87 | P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ", |
| 88 | name->from); | 88 | name->from); |
| @@ -672,9 +672,9 @@ int p9_client_version(struct p9_client *c) | |||
| 672 | c->msize, c->proto_version); | 672 | c->msize, c->proto_version); |
| 673 | 673 | ||
| 674 | switch (c->proto_version) { | 674 | switch (c->proto_version) { |
| 675 | case p9_proto_2010L: | 675 | case p9_proto_2000L: |
| 676 | req = p9_client_rpc(c, P9_TVERSION, "ds", | 676 | req = p9_client_rpc(c, P9_TVERSION, "ds", |
| 677 | c->msize, "9P2010.L"); | 677 | c->msize, "9P2000.L"); |
| 678 | break; | 678 | break; |
| 679 | case p9_proto_2000u: | 679 | case p9_proto_2000u: |
| 680 | req = p9_client_rpc(c, P9_TVERSION, "ds", | 680 | req = p9_client_rpc(c, P9_TVERSION, "ds", |
| @@ -700,8 +700,8 @@ int p9_client_version(struct p9_client *c) | |||
| 700 | } | 700 | } |
| 701 | 701 | ||
| 702 | P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version); | 702 | P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version); |
| 703 | if (!strncmp(version, "9P2010.L", 8)) | 703 | if (!strncmp(version, "9P2000.L", 8)) |
| 704 | c->proto_version = p9_proto_2010L; | 704 | c->proto_version = p9_proto_2000L; |
| 705 | else if (!strncmp(version, "9P2000.u", 8)) | 705 | else if (!strncmp(version, "9P2000.u", 8)) |
| 706 | c->proto_version = p9_proto_2000u; | 706 | c->proto_version = p9_proto_2000u; |
| 707 | else if (!strncmp(version, "9P2000", 6)) | 707 | else if (!strncmp(version, "9P2000", 6)) |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 0aaed4819379..afde1a89fbb3 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 | ||
| @@ -214,6 +220,20 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) | |||
| 214 | return 0; | 220 | return 0; |
| 215 | } | 221 | } |
| 216 | 222 | ||
| 223 | static ssize_t p9_mount_tag_show(struct device *dev, | ||
| 224 | struct device_attribute *attr, char *buf) | ||
| 225 | { | ||
| 226 | struct virtio_chan *chan; | ||
| 227 | struct virtio_device *vdev; | ||
| 228 | |||
| 229 | vdev = dev_to_virtio(dev); | ||
| 230 | chan = vdev->priv; | ||
| 231 | |||
| 232 | return snprintf(buf, chan->tag_len + 1, "%s", chan->tag); | ||
| 233 | } | ||
| 234 | |||
| 235 | static DEVICE_ATTR(mount_tag, 0444, p9_mount_tag_show, NULL); | ||
| 236 | |||
| 217 | /** | 237 | /** |
| 218 | * p9_virtio_probe - probe for existence of 9P virtio channels | 238 | * p9_virtio_probe - probe for existence of 9P virtio channels |
| 219 | * @vdev: virtio device to probe | 239 | * @vdev: virtio device to probe |
| @@ -224,6 +244,8 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) | |||
| 224 | 244 | ||
| 225 | static int p9_virtio_probe(struct virtio_device *vdev) | 245 | static int p9_virtio_probe(struct virtio_device *vdev) |
| 226 | { | 246 | { |
| 247 | __u16 tag_len; | ||
| 248 | char *tag; | ||
| 227 | int err; | 249 | int err; |
| 228 | struct virtio_chan *chan; | 250 | struct virtio_chan *chan; |
| 229 | 251 | ||
| @@ -248,6 +270,28 @@ static int p9_virtio_probe(struct virtio_device *vdev) | |||
| 248 | sg_init_table(chan->sg, VIRTQUEUE_NUM); | 270 | sg_init_table(chan->sg, VIRTQUEUE_NUM); |
| 249 | 271 | ||
| 250 | chan->inuse = false; | 272 | chan->inuse = false; |
| 273 | if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) { | ||
| 274 | vdev->config->get(vdev, | ||
| 275 | offsetof(struct virtio_9p_config, tag_len), | ||
| 276 | &tag_len, sizeof(tag_len)); | ||
| 277 | } else { | ||
| 278 | err = -EINVAL; | ||
| 279 | goto out_free_vq; | ||
| 280 | } | ||
| 281 | tag = kmalloc(tag_len, GFP_KERNEL); | ||
| 282 | if (!tag) { | ||
| 283 | err = -ENOMEM; | ||
| 284 | goto out_free_vq; | ||
| 285 | } | ||
| 286 | vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag), | ||
| 287 | tag, tag_len); | ||
| 288 | chan->tag = tag; | ||
| 289 | chan->tag_len = tag_len; | ||
| 290 | err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); | ||
| 291 | if (err) { | ||
| 292 | kfree(tag); | ||
| 293 | goto out_free_vq; | ||
| 294 | } | ||
| 251 | mutex_lock(&virtio_9p_lock); | 295 | mutex_lock(&virtio_9p_lock); |
| 252 | list_add_tail(&chan->chan_list, &virtio_chan_list); | 296 | list_add_tail(&chan->chan_list, &virtio_chan_list); |
| 253 | mutex_unlock(&virtio_9p_lock); | 297 | mutex_unlock(&virtio_9p_lock); |
| @@ -284,7 +328,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args) | |||
| 284 | 328 | ||
| 285 | mutex_lock(&virtio_9p_lock); | 329 | mutex_lock(&virtio_9p_lock); |
| 286 | list_for_each_entry(chan, &virtio_chan_list, chan_list) { | 330 | list_for_each_entry(chan, &virtio_chan_list, chan_list) { |
| 287 | if (!strcmp(devname, dev_name(&chan->vdev->dev))) { | 331 | if (!strncmp(devname, chan->tag, chan->tag_len)) { |
| 288 | if (!chan->inuse) { | 332 | if (!chan->inuse) { |
| 289 | chan->inuse = true; | 333 | chan->inuse = true; |
| 290 | found = 1; | 334 | found = 1; |
| @@ -323,6 +367,8 @@ static void p9_virtio_remove(struct virtio_device *vdev) | |||
| 323 | mutex_lock(&virtio_9p_lock); | 367 | mutex_lock(&virtio_9p_lock); |
| 324 | list_del(&chan->chan_list); | 368 | list_del(&chan->chan_list); |
| 325 | mutex_unlock(&virtio_9p_lock); | 369 | mutex_unlock(&virtio_9p_lock); |
| 370 | sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); | ||
| 371 | kfree(chan->tag); | ||
| 326 | kfree(chan); | 372 | kfree(chan); |
| 327 | 373 | ||
| 328 | } | 374 | } |
| @@ -332,13 +378,19 @@ static struct virtio_device_id id_table[] = { | |||
| 332 | { 0 }, | 378 | { 0 }, |
| 333 | }; | 379 | }; |
| 334 | 380 | ||
| 381 | static unsigned int features[] = { | ||
| 382 | VIRTIO_9P_MOUNT_TAG, | ||
| 383 | }; | ||
| 384 | |||
| 335 | /* The standard "struct lguest_driver": */ | 385 | /* The standard "struct lguest_driver": */ |
| 336 | static struct virtio_driver p9_virtio_drv = { | 386 | static struct virtio_driver p9_virtio_drv = { |
| 337 | .driver.name = KBUILD_MODNAME, | 387 | .feature_table = features, |
| 338 | .driver.owner = THIS_MODULE, | 388 | .feature_table_size = ARRAY_SIZE(features), |
| 339 | .id_table = id_table, | 389 | .driver.name = KBUILD_MODNAME, |
| 340 | .probe = p9_virtio_probe, | 390 | .driver.owner = THIS_MODULE, |
| 341 | .remove = p9_virtio_remove, | 391 | .id_table = id_table, |
| 392 | .probe = p9_virtio_probe, | ||
| 393 | .remove = p9_virtio_remove, | ||
| 342 | }; | 394 | }; |
| 343 | 395 | ||
| 344 | static struct p9_trans_module p9_virtio_trans = { | 396 | static struct p9_trans_module p9_virtio_trans = { |
