9P2010.L handshake: Add mount option
authorSripathi Kodi <sripathik@in.ibm.com>
Fri, 5 Mar 2010 18:49:11 +0000 (18:49 +0000)
committerEric Van Hensbergen <ericvh@gmail.com>
Fri, 5 Mar 2010 21:04:42 +0000 (15:04 -0600)
Add new mount V9FS mount option to specify protocol version

This patch adds a new mount option to specify protocol version.
With this option it is possible to use "-o version=" switch to
specify 9P protocol version to use. Valid options for version
are:
9p2000
9p2000.u
9p2010.L

Signed-off-by: Sripathi Kodi <sripathik@in.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
include/net/9p/client.h
net/9p/client.c

index fb00b329f0d3dd91d3998871f4dc080d9b4f2065..d40f8c55dfae465e66cee541b220e1f134c540fc 100644 (file)
 /* Number of requests per row */
 #define P9_ROW_MAXTAG 255
 
+/** 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
+ */
+
+enum p9_proto_versions{
+       p9_proto_legacy = 0,
+       p9_proto_2000u = 1,
+       p9_proto_2010L = 2,
+};
+
+
 /**
  * enum p9_trans_status - different states of underlying transports
  * @Connected: transport is connected and healthy
@@ -111,6 +124,7 @@ struct p9_req_t {
  * @lock: protect @fidlist
  * @msize: maximum data size negotiated by protocol
  * @dotu: extension flags negotiated by protocol
+ * @proto_version: 9P protocol version to use
  * @trans_mod: module API instantiated with this client
  * @trans: tranport instance state and API
  * @conn: connection state information used by trans_fd
@@ -138,6 +152,7 @@ struct p9_client {
        spinlock_t lock; /* protect client structure */
        int msize;
        unsigned char dotu;
+       unsigned char proto_version;
        struct p9_trans_module *trans_mod;
        enum p9_trans_status status;
        void *trans;
index 09d4f1e2e4a8cef1974929198e8df452597c40f6..3b5f3c94a6ebe11f9d4482a85d55ee10679bbb30 100644 (file)
@@ -46,6 +46,7 @@ enum {
        Opt_msize,
        Opt_trans,
        Opt_legacy,
+       Opt_version,
        Opt_err,
 };
 
@@ -53,9 +54,30 @@ static const match_table_t tokens = {
        {Opt_msize, "msize=%u"},
        {Opt_legacy, "noextend"},
        {Opt_trans, "trans=%s"},
+       {Opt_version, "version=%s"},
        {Opt_err, NULL},
 };
 
+/* Interpret mount option for protocol version */
+static unsigned char get_protocol_version(const substring_t *name)
+{
+       unsigned char version = -EINVAL;
+       if (!strncmp("9p2000", name->from, name->to-name->from)) {
+               version = p9_proto_legacy;
+               P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n");
+       } 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 {
+               P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ",
+                                                       name->from);
+       }
+       return version;
+}
+
 static struct p9_req_t *
 p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
 
@@ -120,6 +142,12 @@ static int parse_opts(char *opts, struct p9_client *clnt)
                case Opt_legacy:
                        clnt->dotu = 0;
                        break;
+               case Opt_version:
+                       ret = get_protocol_version(&args[0]);
+                       if (ret == -EINVAL)
+                               goto free_and_return;
+                       clnt->proto_version = ret;
+                       break;
                default:
                        continue;
                }