diff options
| -rw-r--r-- | include/net/9p/client.h | 15 | ||||
| -rw-r--r-- | net/9p/client.c | 28 |
2 files changed, 43 insertions, 0 deletions
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index fb00b329f0d3..d40f8c55dfae 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h | |||
| @@ -29,6 +29,19 @@ | |||
| 29 | /* Number of requests per row */ | 29 | /* Number of requests per row */ |
| 30 | #define P9_ROW_MAXTAG 255 | 30 | #define P9_ROW_MAXTAG 255 |
| 31 | 31 | ||
| 32 | /** enum p9_proto_versions - 9P protocol versions | ||
| 33 | * @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u | ||
| 34 | * @p9_proto_2000u: 9P2000.u extension | ||
| 35 | * @p9_proto_2010L: 9P2010.L extension | ||
| 36 | */ | ||
| 37 | |||
| 38 | enum p9_proto_versions{ | ||
| 39 | p9_proto_legacy = 0, | ||
| 40 | p9_proto_2000u = 1, | ||
| 41 | p9_proto_2010L = 2, | ||
| 42 | }; | ||
| 43 | |||
| 44 | |||
| 32 | /** | 45 | /** |
| 33 | * enum p9_trans_status - different states of underlying transports | 46 | * enum p9_trans_status - different states of underlying transports |
| 34 | * @Connected: transport is connected and healthy | 47 | * @Connected: transport is connected and healthy |
| @@ -111,6 +124,7 @@ struct p9_req_t { | |||
| 111 | * @lock: protect @fidlist | 124 | * @lock: protect @fidlist |
| 112 | * @msize: maximum data size negotiated by protocol | 125 | * @msize: maximum data size negotiated by protocol |
| 113 | * @dotu: extension flags negotiated by protocol | 126 | * @dotu: extension flags negotiated by protocol |
| 127 | * @proto_version: 9P protocol version to use | ||
| 114 | * @trans_mod: module API instantiated with this client | 128 | * @trans_mod: module API instantiated with this client |
| 115 | * @trans: tranport instance state and API | 129 | * @trans: tranport instance state and API |
| 116 | * @conn: connection state information used by trans_fd | 130 | * @conn: connection state information used by trans_fd |
| @@ -138,6 +152,7 @@ struct p9_client { | |||
| 138 | spinlock_t lock; /* protect client structure */ | 152 | spinlock_t lock; /* protect client structure */ |
| 139 | int msize; | 153 | int msize; |
| 140 | unsigned char dotu; | 154 | unsigned char dotu; |
| 155 | unsigned char proto_version; | ||
| 141 | struct p9_trans_module *trans_mod; | 156 | struct p9_trans_module *trans_mod; |
| 142 | enum p9_trans_status status; | 157 | enum p9_trans_status status; |
| 143 | void *trans; | 158 | void *trans; |
diff --git a/net/9p/client.c b/net/9p/client.c index 09d4f1e2e4a8..3b5f3c94a6eb 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
| @@ -46,6 +46,7 @@ enum { | |||
| 46 | Opt_msize, | 46 | Opt_msize, |
| 47 | Opt_trans, | 47 | Opt_trans, |
| 48 | Opt_legacy, | 48 | Opt_legacy, |
| 49 | Opt_version, | ||
| 49 | Opt_err, | 50 | Opt_err, |
| 50 | }; | 51 | }; |
| 51 | 52 | ||
| @@ -53,9 +54,30 @@ static const match_table_t tokens = { | |||
| 53 | {Opt_msize, "msize=%u"}, | 54 | {Opt_msize, "msize=%u"}, |
| 54 | {Opt_legacy, "noextend"}, | 55 | {Opt_legacy, "noextend"}, |
| 55 | {Opt_trans, "trans=%s"}, | 56 | {Opt_trans, "trans=%s"}, |
| 57 | {Opt_version, "version=%s"}, | ||
| 56 | {Opt_err, NULL}, | 58 | {Opt_err, NULL}, |
| 57 | }; | 59 | }; |
| 58 | 60 | ||
| 61 | /* Interpret mount option for protocol version */ | ||
| 62 | static unsigned char get_protocol_version(const substring_t *name) | ||
| 63 | { | ||
| 64 | unsigned char version = -EINVAL; | ||
| 65 | if (!strncmp("9p2000", name->from, name->to-name->from)) { | ||
| 66 | version = p9_proto_legacy; | ||
| 67 | P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n"); | ||
| 68 | } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) { | ||
| 69 | version = p9_proto_2000u; | ||
| 70 | P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n"); | ||
| 71 | } else if (!strncmp("9p2010.L", name->from, name->to-name->from)) { | ||
| 72 | version = p9_proto_2010L; | ||
| 73 | P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2010.L\n"); | ||
| 74 | } else { | ||
| 75 | P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ", | ||
| 76 | name->from); | ||
| 77 | } | ||
| 78 | return version; | ||
| 79 | } | ||
| 80 | |||
| 59 | static struct p9_req_t * | 81 | static struct p9_req_t * |
| 60 | p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...); | 82 | p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...); |
| 61 | 83 | ||
| @@ -120,6 +142,12 @@ static int parse_opts(char *opts, struct p9_client *clnt) | |||
| 120 | case Opt_legacy: | 142 | case Opt_legacy: |
| 121 | clnt->dotu = 0; | 143 | clnt->dotu = 0; |
| 122 | break; | 144 | break; |
| 145 | case Opt_version: | ||
| 146 | ret = get_protocol_version(&args[0]); | ||
| 147 | if (ret == -EINVAL) | ||
| 148 | goto free_and_return; | ||
| 149 | clnt->proto_version = ret; | ||
| 150 | break; | ||
| 123 | default: | 151 | default: |
| 124 | continue; | 152 | continue; |
| 125 | } | 153 | } |
