diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt index b22abba78fede6049ab07b8167bce2dedc99fe90..13de64c7f0ab0bf7f347156573e187a0a72ac4a0 100644 --- a/Documentation/filesystems/9p.txt +++ b/Documentation/filesystems/9p.txt @@ -25,6 +25,8 @@ Other applications are described in the following papers: http://xcpu.org/papers/cellfs-talk.pdf * PROSE I/O: Using 9p to enable Application Partitions http://plan9.escet.urjc.es/iwp9/cready/PROSE_iwp9_2006.pdf + * VirtFS: A Virtualization Aware File System pass-through + http://goo.gl/3WPDg USAGE ===== @@ -130,31 +132,20 @@ OPTIONS RESOURCES ========= -Our current recommendation is to use Inferno (http://www.vitanuova.com/nferno/index.html) -as the 9p server. You can start a 9p server under Inferno by issuing the -following command: - ; styxlisten -A tcp!*!564 export '#U*' +Protocol specifications are maintained on github: +http://ericvh.github.com/9p-rfc/ -The -A specifies an unauthenticated export. The 564 is the port # (you may -have to choose a higher port number if running as a normal user). The '#U*' -specifies exporting the root of the Linux name space. You may specify a -subset of the namespace by extending the path: '#U*'/tmp would just export -/tmp. For more information, see the Inferno manual pages covering styxlisten -and export. +9p client and server implementations are listed on +http://9p.cat-v.org/implementations -A Linux version of the 9p server is now maintained under the npfs project -on sourceforge (http://sourceforge.net/projects/npfs). The currently -maintained version is the single-threaded version of the server (named spfs) -available from the same SVN repository. +A 9p2000.L server is being developed by LLNL and can be found +at http://code.google.com/p/diod/ There are user and developer mailing lists available through the v9fs project on sourceforge (http://sourceforge.net/projects/v9fs). -A stand-alone version of the module (which should build for any 2.6 kernel) -is available via (http://github.com/ericvh/9p-sac/tree/master) - -News and other information is maintained on SWiK (http://swik.net/v9fs) -and the Wiki (http://sf.net/apps/mediawiki/v9fs/index.php). +News and other information is maintained on a Wiki. +(http://sf.net/apps/mediawiki/v9fs/index.php). Bug reports may be issued through the kernel.org bugzilla (http://bugzilla.kernel.org) diff --git a/fs/9p/Kconfig b/fs/9p/Kconfig index 814ac4e213a8a2c37873f99a68a7d639d575e6cf..0a93dc1cb4ac92868d1ecd6cbe8da687b23a4001 100644 --- a/fs/9p/Kconfig +++ b/fs/9p/Kconfig @@ -1,6 +1,6 @@ config 9P_FS - tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)" - depends on INET && NET_9P && EXPERIMENTAL + tristate "Plan 9 Resource Sharing Support (9P2000)" + depends on INET && NET_9P help If you say Y here, you will get experimental support for Plan 9 resource sharing via the 9P2000 protocol. @@ -10,7 +10,6 @@ config 9P_FS If unsure, say N. if 9P_FS - config 9P_FSCACHE bool "Enable 9P client caching support (EXPERIMENTAL)" depends on EXPERIMENTAL diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 82a7c38ddad0dec0c9ecded6fcc4d3eb93a50350..691c78f58bef23eaeac32489399479d981397aed 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -259,7 +259,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, if (IS_ERR(inode_fid)) { err = PTR_ERR(inode_fid); mutex_unlock(&v9inode->v_mutex); - goto error; + goto err_clunk_old_fid; } v9inode->writeback_fid = (void *) inode_fid; } @@ -267,8 +267,8 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, /* Since we are opening a file, assign the open fid to the file */ filp = lookup_instantiate_filp(nd, dentry, generic_file_open); if (IS_ERR(filp)) { - p9_client_clunk(ofid); - return PTR_ERR(filp); + err = PTR_ERR(filp); + goto err_clunk_old_fid; } filp->private_data = ofid; #ifdef CONFIG_9P_FSCACHE @@ -278,10 +278,11 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, return 0; error: - if (ofid) - p9_client_clunk(ofid); if (fid) p9_client_clunk(fid); +err_clunk_old_fid: + if (ofid) + p9_client_clunk(ofid); return err; } diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index d2df55b0c2134a35044a583429ac34e01b37f065..008711e8e78f265d512105d788aad6877c016a07 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -241,10 +241,10 @@ enum p9_open_mode_t { /** * enum p9_perm_t - 9P permissions - * @P9_DMDIR: mode bite for directories + * @P9_DMDIR: mode bit for directories * @P9_DMAPPEND: mode bit for is append-only * @P9_DMEXCL: mode bit for excluse use (only one open handle allowed) - * @P9_DMMOUNT: mode bite for mount points + * @P9_DMMOUNT: mode bit for mount points * @P9_DMAUTH: mode bit for authentication file * @P9_DMTMP: mode bit for non-backed-up files * @P9_DMSYMLINK: mode bit for symbolic links (9P2000.u) @@ -362,7 +362,7 @@ struct p9_qid { }; /** - * struct p9_stat - file system metadata information + * struct p9_wstat - file system metadata information * @size: length prefix for this stat structure instance * @type: the type of the server (equivalent to a major number) * @dev: the sub-type of the server (equivalent to a minor number) @@ -687,10 +687,10 @@ struct p9_rwstat { * @size: prefixed length of the structure * @id: protocol operating identifier of type &p9_msg_t * @tag: transaction id of the request - * @offset: used by marshalling routines to track currentposition in buffer + * @offset: used by marshalling routines to track current position in buffer * @capacity: used by marshalling routines to track total malloc'd capacity * @pubuf: Payload user buffer given by the caller - * @pubuf: Payload kernel buffer given by the caller + * @pkbuf: Payload kernel buffer given by the caller * @pbuf_size: pubuf/pkbuf(only one will be !NULL) size to be read/write. * @private: For transport layer's use. * @sdata: payload @@ -714,7 +714,7 @@ struct p9_fcall { size_t pbuf_size; void *private; - uint8_t *sdata; + u8 *sdata; }; struct p9_idpool; @@ -728,7 +728,6 @@ void p9_idpool_put(int id, struct p9_idpool *p); int p9_idpool_check(int id, struct p9_idpool *p); int p9_error_init(void); -int p9_errstr2errno(char *, int); int p9_trans_fd_init(void); void p9_trans_fd_exit(void); #endif /* NET_9P_H */ diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 051a99f79769a59021fdcb958a6f850e1f2ddc71..d26d5e98a1737e85e9e2004f30d5fa17f4f007ae 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -60,7 +60,7 @@ enum p9_trans_status { }; /** - * enum p9_req_status_t - virtio request status + * enum p9_req_status_t - status of a request * @REQ_STATUS_IDLE: request slot unused * @REQ_STATUS_ALLOC: request has been allocated but not sent * @REQ_STATUS_UNSENT: request waiting to be sent diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h index 8f08c736c4c3c22a86988c89c9f5fec77e68ff7b..d8549fb9c742209369f324db5953fd5904aa36dd 100644 --- a/include/net/9p/transport.h +++ b/include/net/9p/transport.h @@ -41,6 +41,7 @@ * @pref: Preferences of this transport * @def: set if this transport should be considered the default * @create: member function to create a new connection on this transport + * @close: member function to discard a connection on this transport * @request: member function to issue a request to the transport * @cancel: member function to cancel a request (if it hasn't been sent) * @@ -48,7 +49,7 @@ * transport module with the 9P core network module and used by the client * to instantiate a new connection on a transport. * - * BUGS: the transport module list isn't protected. + * The transport module list is protected by v9fs_trans_lock. */ struct p9_trans_module { diff --git a/net/9p/Kconfig b/net/9p/Kconfig index 7ed75c7bd5d1384943e7425dd9c81f44983fec8e..d9ea09b11cf8140529b0649b34a5252a551e81b5 100644 --- a/net/9p/Kconfig +++ b/net/9p/Kconfig @@ -3,8 +3,8 @@ # menuconfig NET_9P - depends on NET && EXPERIMENTAL - tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)" + depends on NET + tristate "Plan 9 Resource Sharing Support (9P2000)" help If you say Y here, you will get experimental support for Plan 9 resource sharing via the 9P2000 protocol. @@ -16,8 +16,8 @@ menuconfig NET_9P if NET_9P config NET_9P_VIRTIO - depends on EXPERIMENTAL && VIRTIO - tristate "9P Virtio Transport (Experimental)" + depends on VIRTIO + tristate "9P Virtio Transport" help This builds support for a transports between guest partitions and a host partition. diff --git a/net/9p/client.c b/net/9p/client.c index ceab943dfc496cd10467f78c948d28ebf1d29a93..9e3b0e640da179a122f6f846bd8cff31920db159 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -92,9 +92,6 @@ static int get_protocol_version(const substring_t *name) return version; } -static struct p9_req_t * -p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...); - /** * parse_options - parse mount options into client structure * @opts: options string passed from mount @@ -307,12 +304,13 @@ static int p9_tag_init(struct p9_client *c) c->tagpool = p9_idpool_create(); if (IS_ERR(c->tagpool)) { err = PTR_ERR(c->tagpool); - c->tagpool = NULL; goto error; } - - p9_idpool_get(c->tagpool); /* reserve tag 0 */ - + err = p9_idpool_get(c->tagpool); /* reserve tag 0 */ + if (err < 0) { + p9_idpool_destroy(c->tagpool); + goto error; + } c->max_tag = 0; error: return err; @@ -518,12 +516,15 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) return err; } +static struct p9_req_t * +p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...); + /** * p9_client_flush - flush (cancel) a request * @c: client state * @oldreq: request to cancel * - * This sents a flush for a particular requests and links + * This sents a flush for a particular request and links * the flush request to the original request. The current * code only supports a single flush request although the protocol * allows for multiple flush requests to be sent for a single request. @@ -789,11 +790,13 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) spin_lock_init(&clnt->lock); INIT_LIST_HEAD(&clnt->fidlist); - p9_tag_init(clnt); + err = p9_tag_init(clnt); + if (err < 0) + goto free_client; err = parse_opts(options, clnt); if (err < 0) - goto free_client; + goto destroy_tagpool; if (!clnt->trans_mod) clnt->trans_mod = v9fs_get_default_trans(); @@ -802,13 +805,12 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) err = -EPROTONOSUPPORT; P9_DPRINTK(P9_DEBUG_ERROR, "No transport defined or default transport\n"); - goto free_client; + goto destroy_tagpool; } clnt->fidpool = p9_idpool_create(); if (IS_ERR(clnt->fidpool)) { err = PTR_ERR(clnt->fidpool); - clnt->fidpool = NULL; goto put_trans; } @@ -834,6 +836,8 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) p9_idpool_destroy(clnt->fidpool); put_trans: v9fs_put_trans(clnt->trans_mod); +destroy_tagpool: + p9_idpool_destroy(clnt->tagpool); free_client: kfree(clnt); return ERR_PTR(err); @@ -1298,7 +1302,7 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, if (count < rsize) rsize = count; - /* Don't bother zerocopy form small IO (< 1024) */ + /* Don't bother zerocopy for small IO (< 1024) */ if (((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == P9_TRANS_PREF_PAYLOAD_SEP) && (rsize > 1024)) { req = p9_client_rpc(clnt, P9_TREAD, "dqE", fid->fid, offset, diff --git a/net/9p/mod.c b/net/9p/mod.c index cf8a4128cd5c03560bfb93971779965176bea7dd..72c39827505125b618b7a007b6a1dc23d98b4f4f 100644 --- a/net/9p/mod.c +++ b/net/9p/mod.c @@ -139,7 +139,7 @@ void v9fs_put_trans(struct p9_trans_module *m) } /** - * v9fs_init - Initialize module + * init_p9 - Initialize module * */ static int __init init_p9(void) @@ -154,7 +154,7 @@ static int __init init_p9(void) } /** - * v9fs_init - shutdown module + * exit_p9 - shutdown module * */ diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 4a9084395d358320840a3fdf7398da8b0d85b09b..fdfdb5747f63b6492fc23eafa000dcd7d93c9c5b 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -916,8 +916,8 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args) sin_server.sin_family = AF_INET; sin_server.sin_addr.s_addr = in_aton(addr); sin_server.sin_port = htons(opts.port); - err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); - + err = __sock_create(read_pnet(¤t->nsproxy->net_ns), PF_INET, + SOCK_STREAM, IPPROTO_TCP, &csocket, 1); if (err) { P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n"); return err; @@ -954,7 +954,8 @@ p9_fd_create_unix(struct p9_client *client, const char *addr, char *args) sun_server.sun_family = PF_UNIX; strcpy(sun_server.sun_path, addr); - err = sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); + err = __sock_create(read_pnet(¤t->nsproxy->net_ns), PF_UNIX, + SOCK_STREAM, 0, &csocket, 1); if (err < 0) { P9_EPRINTK(KERN_ERR, "p9_trans_unix: problem creating socket\n"); return err; diff --git a/net/9p/util.c b/net/9p/util.c index da6af81e59d9fa504345c306e6636acd1f91b093..9c1c9348ac35d3410ccb255266f9367bbf5d2549 100644 --- a/net/9p/util.c +++ b/net/9p/util.c @@ -93,7 +93,7 @@ int p9_idpool_get(struct p9_idpool *p) retry: if (idr_pre_get(&p->pool, GFP_NOFS) == 0) - return 0; + return -1; spin_lock_irqsave(&p->lock, flags);