summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Van Hensbergen <ericvh@ericvh-desktop.(none)>2008-03-07 10:53:53 -0600
committerEric Van Hensbergen <ericvh@opteron.9grid.us>2008-05-14 19:23:26 -0500
commitbb8ffdfc3e3b32ad9fcdb8da289088d3b22794e5 (patch)
treefbe3dc4e19b5ca63b0cb548476cbb02cbfc59ee9
parentab31267dfeddf80b2e483f077c8b03905993722b (diff)
downloadlinux-3.10-bb8ffdfc3e3b32ad9fcdb8da289088d3b22794e5.tar.gz
linux-3.10-bb8ffdfc3e3b32ad9fcdb8da289088d3b22794e5.tar.bz2
linux-3.10-bb8ffdfc3e3b32ad9fcdb8da289088d3b22794e5.zip
9p: propagate parse_option changes to client and transports
Propagate changes that were made to the parse_options code to the other parse options pieces present in the other modules. Looks like the client parse options was probably corrupting the parse string and causing problems for others. Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
-rw-r--r--net/9p/client.c30
-rw-r--r--net/9p/trans_fd.c29
2 files changed, 45 insertions, 14 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index 84e087e2414..553c34e9f29 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -64,21 +64,30 @@ static match_table_t tokens = {
* @options: options string passed from mount
* @v9ses: existing v9fs session information
*
+ * Return 0 upon success, -ERRNO upon failure
*/
-static void parse_opts(char *options, struct p9_client *clnt)
+static int parse_opts(char *opts, struct p9_client *clnt)
{
+ char *options;
char *p;
substring_t args[MAX_OPT_ARGS];
int option;
- int ret;
+ int ret = 0;
clnt->trans_mod = v9fs_default_trans();
clnt->dotu = 1;
clnt->msize = 8192;
- if (!options)
- return;
+ if (!opts)
+ return 0;
+
+ options = kstrdup(opts, GFP_KERNEL);
+ if (!options) {
+ P9_DPRINTK(P9_DEBUG_ERROR,
+ "failed to allocate copy of option string\n");
+ return -ENOMEM;
+ }
while ((p = strsep(&options, ",")) != NULL) {
int token;
@@ -86,10 +95,11 @@ static void parse_opts(char *options, struct p9_client *clnt)
continue;
token = match_token(p, tokens, args);
if (token < Opt_trans) {
- ret = match_int(&args[0], &option);
- if (ret < 0) {
+ int r = match_int(&args[0], &option);
+ if (r < 0) {
P9_DPRINTK(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
+ ret = r;
continue;
}
}
@@ -107,6 +117,8 @@ static void parse_opts(char *options, struct p9_client *clnt)
continue;
}
}
+ kfree(options);
+ return ret;
}
@@ -138,6 +150,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
if (!clnt)
return ERR_PTR(-ENOMEM);
+ clnt->trans = NULL;
spin_lock_init(&clnt->lock);
INIT_LIST_HEAD(&clnt->fidlist);
clnt->fidpool = p9_idpool_create();
@@ -147,7 +160,10 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
goto error;
}
- parse_opts(options, clnt);
+ err = parse_opts(options, clnt);
+ if (err < 0)
+ goto error;
+
if (clnt->trans_mod == NULL) {
err = -EPROTONOSUPPORT;
P9_DPRINTK(P9_DEBUG_ERROR,
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index c6eda999fa7..97b103b7049 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -1196,35 +1196,46 @@ void p9_conn_cancel(struct p9_conn *m, int err)
}
/**
- * v9fs_parse_options - parse mount options into session structure
+ * parse_options - parse mount options into session structure
* @options: options string passed from mount
* @opts: transport-specific structure to parse options into
*
+ * Returns 0 upon success, -ERRNO upon failure
*/
-static void parse_opts(char *options, struct p9_fd_opts *opts)
+static int parse_opts(char *params, struct p9_fd_opts *opts)
{
char *p;
substring_t args[MAX_OPT_ARGS];
int option;
+ char *options;
int ret;
opts->port = P9_PORT;
opts->rfd = ~0;
opts->wfd = ~0;
- if (!options)
- return;
+ if (!params)
+ return 0;
+
+ options = kstrdup(params, GFP_KERNEL);
+ if (!options) {
+ P9_DPRINTK(P9_DEBUG_ERROR,
+ "failed to allocate copy of option string\n");
+ return -ENOMEM;
+ }
while ((p = strsep(&options, ",")) != NULL) {
int token;
+ int r;
if (!*p)
continue;
token = match_token(p, tokens, args);
- ret = match_int(&args[0], &option);
- if (ret < 0) {
+ r = match_int(&args[0], &option);
+ if (r < 0) {
P9_DPRINTK(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
+ ret = r;
continue;
}
switch (token) {
@@ -1241,6 +1252,8 @@ static void parse_opts(char *options, struct p9_fd_opts *opts)
continue;
}
}
+ kfree(options);
+ return 0;
}
static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd)
@@ -1430,7 +1443,9 @@ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
struct p9_fd_opts opts;
struct p9_trans_fd *p;
- parse_opts(args, &opts);
+ err = parse_opts(args, &opts);
+ if (err < 0)
+ return ERR_PTR(err);
csocket = NULL;
trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);