Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 14 Mar 2010 18:11:08 +0000 (11:11 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 14 Mar 2010 18:11:08 +0000 (11:11 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
  9p: Skip check for mandatory locks when unlocking
  9p: Fixes a simple bug enabling writes beyond 2GB.
  9p: Change the name of new protocol from 9p2010.L to 9p2000.L
  fs/9p: re-init the wstat in readdir loop
  net/9p: Add sysfs mount_tag file for virtio 9P device
  net/9p: Use the tag name in the config space for identifying mount point

fs/9p/v9fs.h
fs/9p/vfs_dir.c
fs/9p/vfs_file.c
include/linux/virtio.h
include/linux/virtio_9p.h
include/net/9p/client.h
net/9p/client.c
net/9p/trans_virtio.c

index 79000bf624919acf26700d6689ba2d6328108650..6b801d1ddf4b22de50a7d663d220e5e171facfdc 100644 (file)
@@ -24,7 +24,7 @@
 /**
  * enum p9_session_flags - option flags for each 9P session
  * @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions
- * @V9FS_PROTO_2010L: whether or not to use 9P2010.l extensions
+ * @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions
  * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
  * @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
  * @V9FS_ACCESS_ANY: use a single attach for all users
@@ -34,7 +34,7 @@
  */
 enum p9_session_flags {
        V9FS_PROTO_2000U        = 0x01,
-       V9FS_PROTO_2010L        = 0x02,
+       V9FS_PROTO_2000L        = 0x02,
        V9FS_ACCESS_SINGLE      = 0x04,
        V9FS_ACCESS_USER        = 0x08,
        V9FS_ACCESS_ANY         = 0x0C,
@@ -130,5 +130,5 @@ static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
 
 static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
 {
-       return v9ses->flags & V9FS_PROTO_2010L;
+       return v9ses->flags & V9FS_PROTO_2000L;
 }
index 6580aa4495414bd33a2d260eec8eb95c2bc0a59e..d8a3afe4ff722fcac539863e59a3278d459ec0bd 100644 (file)
@@ -76,6 +76,15 @@ static inline int dt_type(struct p9_wstat *mistat)
        return rettype;
 }
 
+static void p9stat_init(struct p9_wstat *stbuf)
+{
+       stbuf->name  = NULL;
+       stbuf->uid   = NULL;
+       stbuf->gid   = NULL;
+       stbuf->muid  = NULL;
+       stbuf->extension = NULL;
+}
+
 /**
  * v9fs_dir_readdir - read a directory
  * @filp: opened file structure
@@ -131,8 +140,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
                        rdir->head = 0;
                        rdir->tail = err;
                }
-
                while (rdir->head < rdir->tail) {
+                       p9stat_init(&st);
                        err = p9stat_read(rdir->buf + rdir->head,
                                                buflen - rdir->head, &st,
                                                fid->clnt->proto_version);
index 36122683fae8df1ff12a21b4454788637f89da1e..df52d488d2a697ad917e53ee96428c7c2714ae98 100644 (file)
@@ -114,7 +114,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
        P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
 
        /* No mandatory locks */
-       if (__mandatory_lock(inode))
+       if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
                return -ENOLCK;
 
        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,
        struct p9_fid *fid;
        struct p9_client *clnt;
        struct inode *inode = filp->f_path.dentry->d_inode;
-       int origin = *offset;
+       loff_t origin = *offset;
        unsigned long pg_start, pg_end;
 
        P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data,
index f508c651e53dec96f7d27a840979fd80a42e0d10..40d1709bdbf4a8b0cc01a7caa132ff0c09c54fda 100644 (file)
@@ -98,6 +98,7 @@ struct virtio_device {
        void *priv;
 };
 
+#define dev_to_virtio(dev) container_of(dev, struct virtio_device, dev)
 int register_virtio_device(struct virtio_device *dev);
 void unregister_virtio_device(struct virtio_device *dev);
 
index 3322750800834ca854bff555a03d567d291a02e2..5cf11765146b11ce43017e702832b4746c7ed87b 100644 (file)
@@ -5,4 +5,16 @@
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 
+/* The feature bitmap for virtio 9P */
+
+/* The mount point is specified in a config variable */
+#define VIRTIO_9P_MOUNT_TAG 0
+
+struct virtio_9p_config {
+       /* length of the tag name */
+       __u16 tag_len;
+       /* non-NULL terminated tag name */
+       __u8 tag[0];
+} __attribute__((packed));
+
 #endif /* _LINUX_VIRTIO_9P_H */
index 52e1fff709e43fbd1f825809036994b5aaa76a87..f076dfa75ae8b28eec5aefc5233a12c55ed459de 100644 (file)
 /** enum p9_proto_versions - 9P protocol versions
  * @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u
  * @p9_proto_2000u: 9P2000.u extension
- * @p9_proto_2010L: 9P2010.L extension
+ * @p9_proto_2000L: 9P2000.L extension
  */
 
 enum p9_proto_versions{
        p9_proto_legacy = 0,
        p9_proto_2000u = 1,
-       p9_proto_2010L = 2,
+       p9_proto_2000L = 2,
 };
 
 
index bde9f3d38c579eca51183cf38cb7f33effad8055..e3e5bf4469ced27351e467b9d3bde3b11291c894 100644 (file)
@@ -60,7 +60,7 @@ static const match_table_t tokens = {
 
 inline int p9_is_proto_dotl(struct p9_client *clnt)
 {
-       return (clnt->proto_version == p9_proto_2010L);
+       return (clnt->proto_version == p9_proto_2000L);
 }
 EXPORT_SYMBOL(p9_is_proto_dotl);
 
@@ -80,9 +80,9 @@ static unsigned char get_protocol_version(const substring_t *name)
        } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) {
                version = p9_proto_2000u;
                P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n");
-       } else if (!strncmp("9p2010.L", name->from, name->to-name->from)) {
-               version = p9_proto_2010L;
-               P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2010.L\n");
+       } else if (!strncmp("9p2000.L", name->from, name->to-name->from)) {
+               version = p9_proto_2000L;
+               P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
        } else {
                P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ",
                                                        name->from);
@@ -672,9 +672,9 @@ int p9_client_version(struct p9_client *c)
                                                c->msize, c->proto_version);
 
        switch (c->proto_version) {
-       case p9_proto_2010L:
+       case p9_proto_2000L:
                req = p9_client_rpc(c, P9_TVERSION, "ds",
-                                       c->msize, "9P2010.L");
+                                       c->msize, "9P2000.L");
                break;
        case p9_proto_2000u:
                req = p9_client_rpc(c, P9_TVERSION, "ds",
@@ -700,8 +700,8 @@ int p9_client_version(struct p9_client *c)
        }
 
        P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
-       if (!strncmp(version, "9P2010.L", 8))
-               c->proto_version = p9_proto_2010L;
+       if (!strncmp(version, "9P2000.L", 8))
+               c->proto_version = p9_proto_2000L;
        else if (!strncmp(version, "9P2000.u", 8))
                c->proto_version = p9_proto_2000u;
        else if (!strncmp(version, "9P2000", 6))
index 0aaed48193795407f87c3a9ecbdf1b7f2869a8b2..afde1a89fbb328d1dbda695c6824e205c7997e1a 100644 (file)
@@ -78,6 +78,12 @@ struct virtio_chan {
        /* Scatterlist: can be too big for stack. */
        struct scatterlist sg[VIRTQUEUE_NUM];
 
+       int tag_len;
+       /*
+        * tag name to identify a mount Non-null terminated
+        */
+       char *tag;
+
        struct list_head chan_list;
 };
 
@@ -214,6 +220,20 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
        return 0;
 }
 
+static ssize_t p9_mount_tag_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct virtio_chan *chan;
+       struct virtio_device *vdev;
+
+       vdev = dev_to_virtio(dev);
+       chan = vdev->priv;
+
+       return snprintf(buf, chan->tag_len + 1, "%s", chan->tag);
+}
+
+static DEVICE_ATTR(mount_tag, 0444, p9_mount_tag_show, NULL);
+
 /**
  * p9_virtio_probe - probe for existence of 9P virtio channels
  * @vdev: virtio device to probe
@@ -224,6 +244,8 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
 
 static int p9_virtio_probe(struct virtio_device *vdev)
 {
+       __u16 tag_len;
+       char *tag;
        int err;
        struct virtio_chan *chan;
 
@@ -248,6 +270,28 @@ static int p9_virtio_probe(struct virtio_device *vdev)
        sg_init_table(chan->sg, VIRTQUEUE_NUM);
 
        chan->inuse = false;
+       if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) {
+               vdev->config->get(vdev,
+                               offsetof(struct virtio_9p_config, tag_len),
+                               &tag_len, sizeof(tag_len));
+       } else {
+               err = -EINVAL;
+               goto out_free_vq;
+       }
+       tag = kmalloc(tag_len, GFP_KERNEL);
+       if (!tag) {
+               err = -ENOMEM;
+               goto out_free_vq;
+       }
+       vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag),
+                       tag, tag_len);
+       chan->tag = tag;
+       chan->tag_len = tag_len;
+       err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
+       if (err) {
+               kfree(tag);
+               goto out_free_vq;
+       }
        mutex_lock(&virtio_9p_lock);
        list_add_tail(&chan->chan_list, &virtio_chan_list);
        mutex_unlock(&virtio_9p_lock);
@@ -284,7 +328,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
 
        mutex_lock(&virtio_9p_lock);
        list_for_each_entry(chan, &virtio_chan_list, chan_list) {
-               if (!strcmp(devname, dev_name(&chan->vdev->dev))) {
+               if (!strncmp(devname, chan->tag, chan->tag_len)) {
                        if (!chan->inuse) {
                                chan->inuse = true;
                                found = 1;
@@ -323,6 +367,8 @@ static void p9_virtio_remove(struct virtio_device *vdev)
        mutex_lock(&virtio_9p_lock);
        list_del(&chan->chan_list);
        mutex_unlock(&virtio_9p_lock);
+       sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
+       kfree(chan->tag);
        kfree(chan);
 
 }
@@ -332,13 +378,19 @@ static struct virtio_device_id id_table[] = {
        { 0 },
 };
 
+static unsigned int features[] = {
+       VIRTIO_9P_MOUNT_TAG,
+};
+
 /* The standard "struct lguest_driver": */
 static struct virtio_driver p9_virtio_drv = {
-       .driver.name =  KBUILD_MODNAME,
-       .driver.owner = THIS_MODULE,
-       .id_table =     id_table,
-       .probe =        p9_virtio_probe,
-       .remove =       p9_virtio_remove,
+       .feature_table  = features,
+       .feature_table_size = ARRAY_SIZE(features),
+       .driver.name    = KBUILD_MODNAME,
+       .driver.owner   = THIS_MODULE,
+       .id_table       = id_table,
+       .probe          = p9_virtio_probe,
+       .remove         = p9_virtio_remove,
 };
 
 static struct p9_trans_module p9_virtio_trans = {