aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/v9fs.h6
-rw-r--r--fs/9p/vfs_dir.c11
-rw-r--r--fs/9p/vfs_file.c4
-rw-r--r--include/linux/virtio.h1
-rw-r--r--include/linux/virtio_9p.h12
-rw-r--r--include/net/9p/client.h4
-rw-r--r--net/9p/client.c16
-rw-r--r--net/9p/trans_virtio.c64
8 files changed, 96 insertions, 22 deletions
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 79000bf62491..6b801d1ddf4b 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -24,7 +24,7 @@
24/** 24/**
25 * enum p9_session_flags - option flags for each 9P session 25 * enum p9_session_flags - option flags for each 9P session
26 * @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions 26 * @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions
27 * @V9FS_PROTO_2010L: whether or not to use 9P2010.l extensions 27 * @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions
28 * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy 28 * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
29 * @V9FS_ACCESS_USER: a new attach will be issued for every user (default) 29 * @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
30 * @V9FS_ACCESS_ANY: use a single attach for all users 30 * @V9FS_ACCESS_ANY: use a single attach for all users
@@ -34,7 +34,7 @@
34 */ 34 */
35enum p9_session_flags { 35enum p9_session_flags {
36 V9FS_PROTO_2000U = 0x01, 36 V9FS_PROTO_2000U = 0x01,
37 V9FS_PROTO_2010L = 0x02, 37 V9FS_PROTO_2000L = 0x02,
38 V9FS_ACCESS_SINGLE = 0x04, 38 V9FS_ACCESS_SINGLE = 0x04,
39 V9FS_ACCESS_USER = 0x08, 39 V9FS_ACCESS_USER = 0x08,
40 V9FS_ACCESS_ANY = 0x0C, 40 V9FS_ACCESS_ANY = 0x0C,
@@ -130,5 +130,5 @@ static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
130 130
131static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses) 131static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
132{ 132{
133 return v9ses->flags & V9FS_PROTO_2010L; 133 return v9ses->flags & V9FS_PROTO_2000L;
134} 134}
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index 6580aa449541..d8a3afe4ff72 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -76,6 +76,15 @@ static inline int dt_type(struct p9_wstat *mistat)
76 return rettype; 76 return rettype;
77} 77}
78 78
79static void p9stat_init(struct p9_wstat *stbuf)
80{
81 stbuf->name = NULL;
82 stbuf->uid = NULL;
83 stbuf->gid = NULL;
84 stbuf->muid = NULL;
85 stbuf->extension = NULL;
86}
87
79/** 88/**
80 * v9fs_dir_readdir - read a directory 89 * v9fs_dir_readdir - read a directory
81 * @filp: opened file structure 90 * @filp: opened file structure
@@ -131,8 +140,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
131 rdir->head = 0; 140 rdir->head = 0;
132 rdir->tail = err; 141 rdir->tail = err;
133 } 142 }
134
135 while (rdir->head < rdir->tail) { 143 while (rdir->head < rdir->tail) {
144 p9stat_init(&st);
136 err = p9stat_read(rdir->buf + rdir->head, 145 err = p9stat_read(rdir->buf + rdir->head,
137 buflen - rdir->head, &st, 146 buflen - rdir->head, &st,
138 fid->clnt->proto_version); 147 fid->clnt->proto_version);
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 36122683fae8..df52d488d2a6 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -114,7 +114,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
114 P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); 114 P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
115 115
116 /* No mandatory locks */ 116 /* No mandatory locks */
117 if (__mandatory_lock(inode)) 117 if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
118 return -ENOLCK; 118 return -ENOLCK;
119 119
120 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { 120 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
@@ -215,7 +215,7 @@ v9fs_file_write(struct file *filp, const char __user * data,
215 struct p9_fid *fid; 215 struct p9_fid *fid;
216 struct p9_client *clnt; 216 struct p9_client *clnt;
217 struct inode *inode = filp->f_path.dentry->d_inode; 217 struct inode *inode = filp->f_path.dentry->d_inode;
218 int origin = *offset; 218 loff_t origin = *offset;
219 unsigned long pg_start, pg_end; 219 unsigned long pg_start, pg_end;
220 220
221 P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, 221 P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data,
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index f508c651e53d..40d1709bdbf4 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -98,6 +98,7 @@ struct virtio_device {
98 void *priv; 98 void *priv;
99}; 99};
100 100
101#define dev_to_virtio(dev) container_of(dev, struct virtio_device, dev)
101int register_virtio_device(struct virtio_device *dev); 102int register_virtio_device(struct virtio_device *dev);
102void unregister_virtio_device(struct virtio_device *dev); 103void unregister_virtio_device(struct virtio_device *dev);
103 104
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
13struct 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/include/net/9p/client.h b/include/net/9p/client.h
index 52e1fff709e4..f076dfa75ae8 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -32,13 +32,13 @@
32/** enum p9_proto_versions - 9P protocol versions 32/** enum p9_proto_versions - 9P protocol versions
33 * @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u 33 * @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u
34 * @p9_proto_2000u: 9P2000.u extension 34 * @p9_proto_2000u: 9P2000.u extension
35 * @p9_proto_2010L: 9P2010.L extension 35 * @p9_proto_2000L: 9P2000.L extension
36 */ 36 */
37 37
38enum p9_proto_versions{ 38enum p9_proto_versions{
39 p9_proto_legacy = 0, 39 p9_proto_legacy = 0,
40 p9_proto_2000u = 1, 40 p9_proto_2000u = 1,
41 p9_proto_2010L = 2, 41 p9_proto_2000L = 2,
42}; 42};
43 43
44 44
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
61inline int p9_is_proto_dotl(struct p9_client *clnt) 61inline 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}
65EXPORT_SYMBOL(p9_is_proto_dotl); 65EXPORT_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
223static 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
235static 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
225static int p9_virtio_probe(struct virtio_device *vdev) 245static 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
381static unsigned int features[] = {
382 VIRTIO_9P_MOUNT_TAG,
383};
384
335/* The standard "struct lguest_driver": */ 385/* The standard "struct lguest_driver": */
336static struct virtio_driver p9_virtio_drv = { 386static 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
344static struct p9_trans_module p9_virtio_trans = { 396static struct p9_trans_module p9_virtio_trans = {