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 p9_tag_init(struct p9_client *c) { int err = 0; c->tagpool = p9_idpool_create(); if (IS_ERR(c->tagpool)) { err = PTR_ERR(c->tagpool); c->tagpool = NULL; goto error; } p9_idpool_get(c->tagpool); /* reserve tag 0 */ c->max_tag = 0; error: return err; }
struct p9_client *p9_client_create(struct p9_trans *trans, int msize, int dotu) { int err, n; struct p9_client *clnt; struct p9_fcall *tc, *rc; struct p9_str *version; err = 0; tc = NULL; rc = NULL; clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL); if (!clnt) return ERR_PTR(-ENOMEM); P9_DPRINTK(P9_DEBUG_9P, "clnt %p trans %p msize %d dotu %d\n", clnt, trans, msize, dotu); spin_lock_init(&clnt->lock); clnt->trans = trans; clnt->msize = msize; clnt->dotu = dotu; INIT_LIST_HEAD(&clnt->fidlist); clnt->fidpool = p9_idpool_create(); if (!clnt->fidpool) { err = PTR_ERR(clnt->fidpool); clnt->fidpool = NULL; goto error; } clnt->conn = p9_conn_create(clnt->trans, clnt->msize, &clnt->dotu); if (IS_ERR(clnt->conn)) { err = PTR_ERR(clnt->conn); clnt->conn = NULL; goto error; } tc = p9_create_tversion(clnt->msize, clnt->dotu?"9P2000.u":"9P2000"); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; goto error; } err = p9_conn_rpc(clnt->conn, tc, &rc); if (err) goto error; version = &rc->params.rversion.version; if (version->len == 8 && !memcmp(version->str, "9P2000.u", 8)) clnt->dotu = 1; else if (version->len == 6 && !memcmp(version->str, "9P2000", 6)) clnt->dotu = 0; else { err = -EREMOTEIO; goto error; } n = rc->params.rversion.msize; if (n < clnt->msize) clnt->msize = n; kfree(tc); kfree(rc); return clnt; error: kfree(tc); kfree(rc); p9_client_destroy(clnt); return ERR_PTR(err); }