struct p9_client *p9_client_create(const char *dev_name, char *options) { int err; struct p9_client *clnt; err = 0; clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL); 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 (IS_ERR(clnt->fidpool)) { err = PTR_ERR(clnt->fidpool); clnt->fidpool = NULL; goto error; } p9_tag_init(clnt); err = parse_opts(options, clnt); if (err < 0) goto error; if (!clnt->trans_mod) clnt->trans_mod = v9fs_get_default_trans(); if (clnt->trans_mod == NULL) { err = -EPROTONOSUPPORT; P9_DPRINTK(P9_DEBUG_ERROR, "No transport defined or default transport\n"); goto error; } P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d dotu %d\n", clnt, clnt->trans_mod, clnt->msize, clnt->dotu); err = clnt->trans_mod->create(clnt, dev_name, options); if (err) goto error; if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize) clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ; err = p9_client_version(clnt); if (err) goto error; return clnt; error: p9_client_destroy(clnt); return ERR_PTR(err); }
static int parse_opts(char *opts, struct p9_client *clnt) { char *options; char *p; substring_t args[MAX_OPT_ARGS]; int option; int ret = 0; clnt->dotu = 1; clnt->msize = 8192; 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; if (!*p) continue; token = match_token(p, tokens, args); if (token < Opt_trans) { int 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) { case Opt_msize: clnt->msize = option; break; case Opt_trans: clnt->trans_mod = v9fs_get_trans_by_name(&args[0]); break; case Opt_legacy: clnt->dotu = 0; break; default: continue; } } if (!clnt->trans_mod) clnt->trans_mod = v9fs_get_default_trans(); kfree(options); return ret; }