Merge branch 'pandora-27-omap1' into rev2
[pandora-kernel.git] / net / 9p / client.c
index 84e087e..10e3203 100644 (file)
@@ -64,21 +64,29 @@ 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 +94,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;
                        }
                }
@@ -98,7 +107,7 @@ static void parse_opts(char *options, struct p9_client *clnt)
                        clnt->msize = option;
                        break;
                case Opt_trans:
-                       clnt->trans_mod = v9fs_match_trans(&args[0]);
+                       clnt->trans_mod = v9fs_get_trans_by_name(&args[0]);
                        break;
                case Opt_legacy:
                        clnt->dotu = 0;
@@ -107,6 +116,12 @@ static void parse_opts(char *options, struct p9_client *clnt)
                        continue;
                }
        }
+
+       if (!clnt->trans_mod)
+               clnt->trans_mod = v9fs_get_default_trans();
+
+       kfree(options);
+       return ret;
 }
 
 
@@ -138,16 +153,21 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
        if (!clnt)
                return ERR_PTR(-ENOMEM);
 
+       clnt->trans_mod = NULL;
+       clnt->trans = NULL;
        spin_lock_init(&clnt->lock);
        INIT_LIST_HEAD(&clnt->fidlist);
        clnt->fidpool = p9_idpool_create();
-       if (!clnt->fidpool) {
+       if (IS_ERR(clnt->fidpool)) {
                err = PTR_ERR(clnt->fidpool);
                clnt->fidpool = NULL;
                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,
@@ -219,6 +239,8 @@ void p9_client_destroy(struct p9_client *clnt)
                clnt->trans = NULL;
        }
 
+       v9fs_put_trans(clnt->trans_mod);
+
        list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)
                p9_fid_destroy(fid);