From 476ada0436351672fbf482db54cb94b8ba877709 Mon Sep 17 00:00:00 2001 From: Sripathi Kodi Date: Wed, 17 Mar 2010 17:02:38 +0000 Subject: [PATCH 1/8] 9p: Fix setting of protocol flags in v9fs_session_info structure. This patch fixes a simple bug I left behind in my earlier protocol negotiation patch. Thanks, Sripathi. Signed-off-by: Sripathi Kodi Signed-off-by: Eric Van Hensbergen --- fs/9p/v9fs.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 6c7f6a251115..2f814cf0c731 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -241,7 +241,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, list_add(&v9ses->slist, &v9fs_sessionlist); spin_unlock(&v9fs_sessionlist_lock); - v9ses->flags = V9FS_PROTO_2000U | V9FS_ACCESS_USER; + v9ses->flags = V9FS_ACCESS_USER; strcpy(v9ses->uname, V9FS_DEFUSER); strcpy(v9ses->aname, V9FS_DEFANAME); v9ses->uid = ~0; @@ -262,8 +262,10 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, goto error; } - if (!p9_is_proto_dotu(v9ses->clnt)) - v9ses->flags &= ~V9FS_PROTO_2000U; + if (p9_is_proto_dotl(v9ses->clnt)) + v9ses->flags |= V9FS_PROTO_2000L; + else if (p9_is_proto_dotu(v9ses->clnt)) + v9ses->flags |= V9FS_PROTO_2000U; v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; From 9208d24253e5e644f8cb1b87b69de44897668303 Mon Sep 17 00:00:00 2001 From: Sripathi Kodi Date: Thu, 18 Mar 2010 08:01:33 +0000 Subject: [PATCH 2/8] 9p: documentation update This patch adds documentation for new 9P options introduced in 2.6.34. Signed-off-by: Sripathi Kodi Signed-off-by: Eric Van Hensbergen --- Documentation/filesystems/9p.txt | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt index 57e0b80a5274..c0236e753bc8 100644 --- a/Documentation/filesystems/9p.txt +++ b/Documentation/filesystems/9p.txt @@ -37,6 +37,15 @@ For Plan 9 From User Space applications (http://swtch.com/plan9) mount -t 9p `namespace`/acme /mnt/9 -o trans=unix,uname=$USER +For server running on QEMU host with virtio transport: + + mount -t 9p -o trans=virtio /mnt/9 + +where mount_tag is the tag associated by the server to each of the exported +mount points. Each 9P export is seen by the client as a virtio device with an +associated "mount_tag" property. Available mount tags can be +seen by reading /sys/bus/virtio/drivers/9pnet_virtio/virtio/mount_tag files. + OPTIONS ======= @@ -47,7 +56,7 @@ OPTIONS fd - used passed file descriptors for connection (see rfdno and wfdno) virtio - connect to the next virtio channel available - (from lguest or KVM with trans_virtio module) + (from QEMU with trans_virtio module) rdma - connect to a specified RDMA channel uname=name user name to attempt mount as on the remote server. The @@ -85,7 +94,12 @@ OPTIONS port=n port to connect to on the remote server - noextend force legacy mode (no 9p2000.u semantics) + noextend force legacy mode (no 9p2000.u or 9p2000.L semantics) + + version=name Select 9P protocol version. Valid options are: + 9p2000 - Legacy mode (same as noextend) + 9p2000.u - Use 9P2000.u protocol + 9p2000.L - Use 9P2000.L protocol dfltuid attempt to mount as a particular uid From 5b0fa207d1a6f27c9a2f2d707147dce01af21db7 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 19 Mar 2010 12:47:26 +0000 Subject: [PATCH 3/8] fs/9p: Clunk the fid resulting from partial walk of the name Signed-off-by: Aneesh Kumar K.V Signed-off-by: Eric Van Hensbergen --- fs/9p/fid.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 08b2eb157048..b0a23c7e736e 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -110,7 +110,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) { int i, n, l, clone, any, access; u32 uid; - struct p9_fid *fid; + struct p9_fid *fid, *old_fid = NULL; struct dentry *d, *ds; struct v9fs_session_info *v9ses; char **wnames, *uname; @@ -183,10 +183,18 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) l = min(n - i, P9_MAXWELEM); fid = p9_client_walk(fid, l, &wnames[i], clone); if (IS_ERR(fid)) { + if (old_fid) { + /* + * If we fail, clunk fid which are mapping + * to path component and not the last component + * of the path. + */ + p9_client_clunk(old_fid); + } kfree(wnames); return fid; } - + old_fid = fid; i += l; clone = 0; } From d994f4058d9f9be7e44529b55fc6be6552901ead Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 29 Mar 2010 18:14:50 -0500 Subject: [PATCH 4/8] 9p: drop nlink remove We need to drop the link count on the inode of a sucessfull remove Signed-off-by: Aneesh Kumar K.V Signed-off-by: Eric Van Hensbergen --- fs/9p/vfs_inode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 5fe45d692c9f..ae8396707707 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -431,6 +431,7 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) { + int retval; struct inode *file_inode; struct v9fs_session_info *v9ses; struct p9_fid *v9fid; @@ -444,7 +445,10 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) if (IS_ERR(v9fid)) return PTR_ERR(v9fid); - return p9_client_remove(v9fid); + retval = p9_client_remove(v9fid); + if (!retval) + drop_nlink(file_inode); + return retval; } static int From 6d96d3ab7aea5f0e75205a0c97f8d1fdf82c5287 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 29 Mar 2010 18:13:59 -0500 Subject: [PATCH 5/8] 9p: Make sure we are able to clunk the cached fid on umount dcache prune happen on umount. So we cannot mark the client satus disconnect. That will prevent a 9p call to the server Signed-off-by: Aneesh Kumar K.V Signed-off-by: Eric Van Hensbergen --- fs/9p/v9fs.c | 13 +++++++++++++ fs/9p/v9fs.h | 1 + fs/9p/vfs_super.c | 3 ++- include/net/9p/client.h | 2 ++ net/9p/client.c | 18 ++++++++++++++++-- 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 2f814cf0c731..0b78ae8157b9 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -342,6 +342,19 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses) { p9_client_disconnect(v9ses->clnt); } +/** + * v9fs_session_begin_cancel - Begin terminate of a session + * @v9ses: session to terminate + * + * After this call we don't allow any request other than clunk. + */ + +void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses) +{ + P9_DPRINTK(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses); + p9_client_begin_disconnect(v9ses->clnt); +} + extern int v9fs_error_init(void); static struct kobject *v9fs_kobj; diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 6b801d1ddf4b..a0a8d3dd1361 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -108,6 +108,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, char *); void v9fs_session_close(struct v9fs_session_info *v9ses); void v9fs_session_cancel(struct v9fs_session_info *v9ses); +void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses); #define V9FS_MAGIC 0x01021997 diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 69357c0d9899..d1a3c809a291 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -193,6 +193,7 @@ static void v9fs_kill_super(struct super_block *s) kill_anon_super(s); + v9fs_session_cancel(v9ses); v9fs_session_close(v9ses); kfree(v9ses); s->s_fs_info = NULL; @@ -205,7 +206,7 @@ v9fs_umount_begin(struct super_block *sb) struct v9fs_session_info *v9ses; v9ses = sb->s_fs_info; - v9fs_session_cancel(v9ses); + v9fs_session_begin_cancel(v9ses); } static const struct super_operations v9fs_super_ops = { diff --git a/include/net/9p/client.h b/include/net/9p/client.h index f076dfa75ae8..4f3760afc20f 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -54,6 +54,7 @@ enum p9_proto_versions{ enum p9_trans_status { Connected, + BeginDisconnect, Disconnected, Hung, }; @@ -198,6 +199,7 @@ int p9_client_version(struct p9_client *); struct p9_client *p9_client_create(const char *dev_name, char *options); void p9_client_destroy(struct p9_client *clnt); void p9_client_disconnect(struct p9_client *clnt); +void p9_client_begin_disconnect(struct p9_client *clnt); struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, char *uname, u32 n_uname, char *aname); struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, diff --git a/net/9p/client.c b/net/9p/client.c index e3e5bf4469ce..a037a29f3f0e 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -533,7 +533,12 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type); - if (c->status != Connected) + /* we allow for any status other than disconnected */ + if (c->status == Disconnected) + return ERR_PTR(-EIO); + + /* if status is begin_disconnected we allow only clunk request */ + if ((c->status == BeginDisconnect) && (type != P9_TCLUNK)) return ERR_PTR(-EIO); if (signal_pending(current)) { @@ -799,8 +804,10 @@ void p9_client_destroy(struct p9_client *clnt) v9fs_put_trans(clnt->trans_mod); - list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) + list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) { + printk(KERN_INFO "Found fid %d not clunked\n", fid->fid); p9_fid_destroy(fid); + } if (clnt->fidpool) p9_idpool_destroy(clnt->fidpool); @@ -818,6 +825,13 @@ void p9_client_disconnect(struct p9_client *clnt) } EXPORT_SYMBOL(p9_client_disconnect); +void p9_client_begin_disconnect(struct p9_client *clnt) +{ + P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); + clnt->status = BeginDisconnect; +} +EXPORT_SYMBOL(p9_client_begin_disconnect); + struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, char *uname, u32 n_uname, char *aname) { From 11e9b49b7fa056bfc00a56de8956d1d5fe8b84ea Mon Sep 17 00:00:00 2001 From: Sripathi Kodi Date: Mon, 29 Mar 2010 18:13:59 -0500 Subject: [PATCH 6/8] 9p: Creating files with names too long should fail with ENAMETOOLONG. Signed-off-by: Sripathi Kodi Signed-off-by: Eric Van Hensbergen --- fs/9p/vfs_inode.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index ae8396707707..905f664b8bc6 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -660,6 +660,9 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", dir, dentry->d_name.name, dentry, nameidata); + if (dentry->d_name.len > NAME_MAX) + return ERR_PTR(-ENAMETOOLONG); + sb = dir->i_sb; v9ses = v9fs_inode2v9ses(dir); dfid = v9fs_fid_lookup(dentry->d_parent); From 85a770a8889035625466a4cfb1393cd7d2ffd165 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 30 Mar 2010 09:41:25 +0000 Subject: [PATCH 7/8] 9p: return on mutex_lock_interruptible() If "err" is -EINTR here the original code calls mutex_unlock() and then returns, but it should just return directly. Signed-off-by: Dan Carpenter Signed-off-by: Eric Van Hensbergen ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev --- fs/9p/vfs_dir.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index d8a3afe4ff72..bbe00cf799fa 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -130,6 +130,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) rdir = (struct p9_rdir *) fid->rdir; err = mutex_lock_interruptible(&rdir->mutex); + if (err) + return err; while (err == 0) { if (rdir->tail == rdir->head) { err = v9fs_file_readn(filp, rdir->buf, NULL, From 3dc9fef67f6292692dba181a6d0fd0211bd0a607 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 5 Apr 2010 14:37:28 -0500 Subject: [PATCH 8/8] 9p: saving negative to unsigned char Saving -EINVAL as unsigned char truncates the high bits and changes it into 234 instead of -22. This breaks the test for "if (ret == -EINVAL)" in parse_opts(). Signed-off-by: Dan Carpenter Signed-off-by: Eric Van Hensbergen --- net/9p/client.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/9p/client.c b/net/9p/client.c index a037a29f3f0e..20a33194d66e 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -71,9 +71,10 @@ inline int p9_is_proto_dotu(struct p9_client *clnt) EXPORT_SYMBOL(p9_is_proto_dotu); /* Interpret mount option for protocol version */ -static unsigned char get_protocol_version(const substring_t *name) +static int get_protocol_version(const substring_t *name) { - unsigned char version = -EINVAL; + int version = -EINVAL; + if (!strncmp("9p2000", name->from, name->to-name->from)) { version = p9_proto_legacy; P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n");