struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, const char *dev_name, char *data) { int retval = -EINVAL; struct p9_transport *trans; struct p9_fid *fid; v9ses->name = __getname(); if (!v9ses->name) return ERR_PTR(-ENOMEM); v9ses->remotename = __getname(); if (!v9ses->remotename) { __putname(v9ses->name); return ERR_PTR(-ENOMEM); } strcpy(v9ses->name, V9FS_DEFUSER); strcpy(v9ses->remotename, V9FS_DEFANAME); v9fs_parse_options(data, v9ses); switch (v9ses->proto) { case PROTO_TCP: trans = p9_trans_create_tcp(dev_name, v9ses->port); break; case PROTO_UNIX: trans = p9_trans_create_unix(dev_name); *v9ses->remotename = 0; break; case PROTO_FD: trans = p9_trans_create_fd(v9ses->rfdno, v9ses->wfdno); *v9ses->remotename = 0; break; #ifdef CONFIG_PCI_9P case PROTO_PCI: trans = p9pci_trans_create(); *v9ses->remotename = 0; break; #endif default: printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto); retval = -ENOPROTOOPT; goto error; }; if (IS_ERR(trans)) { retval = PTR_ERR(trans); trans = NULL; goto error; } v9ses->clnt = p9_client_create(trans, v9ses->maxdata + P9_IOHDRSZ, v9ses->extended); if (IS_ERR(v9ses->clnt)) { retval = PTR_ERR(v9ses->clnt); v9ses->clnt = NULL; P9_DPRINTK(P9_DEBUG_ERROR, "problem initializing 9p client\n"); goto error; } fid = p9_client_attach(v9ses->clnt, NULL, v9ses->name, v9ses->remotename); if (IS_ERR(fid)) { retval = PTR_ERR(fid); fid = NULL; P9_DPRINTK(P9_DEBUG_ERROR, "cannot attach\n"); goto error; } return fid; error: v9fs_session_close(v9ses); return ERR_PTR(retval); }
int v9fs_session_init(struct v9fs_session_info *v9ses, const char *dev_name, char *data) { struct v9fs_fcall *fcall = NULL; struct v9fs_transport *trans_proto; int n = 0; int newfid = -1; int retval = -EINVAL; struct v9fs_str *version; v9ses->name = __getname(); if (!v9ses->name) return -ENOMEM; v9ses->remotename = __getname(); if (!v9ses->remotename) { __putname(v9ses->name); return -ENOMEM; } strcpy(v9ses->name, V9FS_DEFUSER); strcpy(v9ses->remotename, V9FS_DEFANAME); v9fs_parse_options(data, v9ses); /* set global debug level */ v9fs_debug_level = v9ses->debug; /* id pools that are session-dependent: fids and tags */ idr_init(&v9ses->fidpool.pool); init_MUTEX(&v9ses->fidpool.lock); switch (v9ses->proto) { case PROTO_TCP: trans_proto = &v9fs_trans_tcp; break; case PROTO_UNIX: trans_proto = &v9fs_trans_unix; *v9ses->remotename = 0; break; case PROTO_FD: trans_proto = &v9fs_trans_fd; *v9ses->remotename = 0; break; default: printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto); retval = -ENOPROTOOPT; goto SessCleanUp; }; v9ses->transport = kmalloc(sizeof(*v9ses->transport), GFP_KERNEL); if (!v9ses->transport) { retval = -ENOMEM; goto SessCleanUp; } memmove(v9ses->transport, trans_proto, sizeof(*v9ses->transport)); if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { eprintk(KERN_ERR, "problem initializing transport\n"); goto SessCleanUp; } v9ses->inprogress = 0; v9ses->shutdown = 0; v9ses->session_hung = 0; v9ses->mux = v9fs_mux_init(v9ses->transport, v9ses->maxdata + V9FS_IOHDRSZ, &v9ses->extended); if (IS_ERR(v9ses->mux)) { retval = PTR_ERR(v9ses->mux); v9ses->mux = NULL; dprintk(DEBUG_ERROR, "problem initializing mux\n"); goto SessCleanUp; } if (v9ses->afid == ~0) { if (v9ses->extended) retval = v9fs_t_version(v9ses, v9ses->maxdata, "9P2000.u", &fcall); else retval = v9fs_t_version(v9ses, v9ses->maxdata, "9P2000", &fcall); if (retval < 0) { dprintk(DEBUG_ERROR, "v9fs_t_version failed\n"); goto FreeFcall; } version = &fcall->params.rversion.version; if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) { dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); v9ses->extended = 1; } else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) { dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); v9ses->extended = 0; } else { retval = -EREMOTEIO; goto FreeFcall; } n = fcall->params.rversion.msize; kfree(fcall); if (n < v9ses->maxdata) v9ses->maxdata = n; } newfid = v9fs_get_idpool(&v9ses->fidpool); if (newfid < 0) { eprintk(KERN_WARNING, "couldn't allocate FID\n"); retval = -ENOMEM; goto SessCleanUp; } /* it is a little bit ugly, but we have to prevent newfid */ /* being the same as afid, so if it is, get a new fid */ if (v9ses->afid != ~0 && newfid == v9ses->afid) { newfid = v9fs_get_idpool(&v9ses->fidpool); if (newfid < 0) { eprintk(KERN_WARNING, "couldn't allocate FID\n"); retval = -ENOMEM; goto SessCleanUp; } } if ((retval = v9fs_t_attach(v9ses, v9ses->name, v9ses->remotename, newfid, v9ses->afid, NULL)) < 0) { dprintk(DEBUG_ERROR, "cannot attach\n"); goto SessCleanUp; } if (v9ses->afid != ~0) { dprintk(DEBUG_ERROR, "afid not equal to ~0\n"); if (v9fs_t_clunk(v9ses, v9ses->afid)) dprintk(DEBUG_ERROR, "clunk failed\n"); } return newfid; FreeFcall: kfree(fcall); SessCleanUp: v9fs_session_close(v9ses); return retval; }
struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, const char *dev_name, char *data) { int retval = -EINVAL; struct p9_fid *fid; int rc; v9ses->uname = __getname(); if (!v9ses->uname) return ERR_PTR(-ENOMEM); v9ses->aname = __getname(); if (!v9ses->aname) { __putname(v9ses->uname); return ERR_PTR(-ENOMEM); } v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER; strcpy(v9ses->uname, V9FS_DEFUSER); strcpy(v9ses->aname, V9FS_DEFANAME); v9ses->uid = ~0; v9ses->dfltuid = V9FS_DEFUID; v9ses->dfltgid = V9FS_DEFGID; if (data) { v9ses->options = kstrdup(data, GFP_KERNEL); if (!v9ses->options) { P9_DPRINTK(P9_DEBUG_ERROR, "failed to allocate copy of option string\n"); retval = -ENOMEM; goto error; } } rc = v9fs_parse_options(v9ses); if (rc < 0) { retval = rc; goto error; } v9ses->clnt = p9_client_create(dev_name, v9ses->options); if (IS_ERR(v9ses->clnt)) { retval = PTR_ERR(v9ses->clnt); v9ses->clnt = NULL; P9_DPRINTK(P9_DEBUG_ERROR, "problem initializing 9p client\n"); goto error; } if (!v9ses->clnt->dotu) v9ses->flags &= ~V9FS_EXTENDED; v9ses->maxdata = v9ses->clnt->msize; /* for legacy mode, fall back to V9FS_ACCESS_ANY */ if (!v9fs_extended(v9ses) && ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) { v9ses->flags &= ~V9FS_ACCESS_MASK; v9ses->flags |= V9FS_ACCESS_ANY; v9ses->uid = ~0; } fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0, v9ses->aname); if (IS_ERR(fid)) { retval = PTR_ERR(fid); fid = NULL; P9_DPRINTK(P9_DEBUG_ERROR, "cannot attach\n"); goto error; } if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE) fid->uid = v9ses->uid; else fid->uid = ~0; return fid; error: return ERR_PTR(retval); }