/**
* 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
*/
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,
static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
{
- return v9ses->flags & V9FS_PROTO_2010L;
+ return v9ses->flags & V9FS_PROTO_2000L;
}
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
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);
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) {
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,
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);
#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 */
/** 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,
};
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);
} 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);
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",
}
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))
/* 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;
};
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
static int p9_virtio_probe(struct virtio_device *vdev)
{
+ __u16 tag_len;
+ char *tag;
int err;
struct virtio_chan *chan;
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);
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;
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);
}
{ 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 = {