struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, char *uname, u32 n_uname, char *aname) { int err; struct p9_req_t *req; struct p9_fid *fid; struct p9_qid qid; P9_DPRINTK(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n", afid ? afid->fid : -1, uname, aname); err = 0; fid = p9_fid_create(clnt); if (IS_ERR(fid)) { err = PTR_ERR(fid); fid = NULL; goto error; } req = p9_client_rpc(clnt, P9_TATTACH, "ddss?d", fid->fid, afid ? afid->fid : P9_NOFID, uname, aname, n_uname); if (IS_ERR(req)) { err = PTR_ERR(req); goto error; } err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid); if (err) { p9pdu_dump(1, req->rc); p9_free_req(clnt, req); goto error; } P9_DPRINTK(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n", qid.type, (unsigned long long)qid.path, qid.version); memmove(&fid->qid, &qid, sizeof(struct p9_qid)); p9_free_req(clnt, req); return fid; error: if (fid) p9_fid_destroy(fid); return ERR_PTR(err); }
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, char *uname, u32 n_uname, char *aname) { int err; struct p9_fcall *tc, *rc; struct p9_fid *fid; P9_DPRINTK(P9_DEBUG_9P, "clnt %p afid %d uname %s aname %s\n", clnt, afid?afid->fid:-1, uname, aname); err = 0; tc = NULL; rc = NULL; fid = p9_fid_create(clnt); if (IS_ERR(fid)) { err = PTR_ERR(fid); fid = NULL; goto error; } tc = p9_create_tattach(fid->fid, afid?afid->fid:P9_NOFID, uname, aname, n_uname, clnt->dotu); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; goto error; } err = p9_conn_rpc(clnt->conn, tc, &rc); if (err) goto error; memmove(&fid->qid, &rc->params.rattach.qid, sizeof(struct p9_qid)); kfree(tc); kfree(rc); return fid; error: kfree(tc); kfree(rc); if (fid) p9_fid_destroy(fid); return ERR_PTR(err); }
struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, int clone) { int err; struct p9_client *clnt; struct p9_fid *fid; struct p9_qid *wqids; struct p9_req_t *req; int16_t nwqids, count; err = 0; clnt = oldfid->clnt; if (clone) { fid = p9_fid_create(clnt); if (IS_ERR(fid)) { err = PTR_ERR(fid); fid = NULL; goto error; } fid->uid = oldfid->uid; } else fid = oldfid; P9_DPRINTK(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %d wname[0] %s\n", oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL); req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid, nwname, wnames); if (IS_ERR(req)) { err = PTR_ERR(req); goto error; } err = p9pdu_readf(req->rc, clnt->dotu, "R", &nwqids, &wqids); if (err) { p9pdu_dump(1, req->rc); p9_free_req(clnt, req); goto clunk_fid; } p9_free_req(clnt, req); P9_DPRINTK(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids); if (nwqids != nwname) { err = -ENOENT; goto clunk_fid; } for (count = 0; count < nwqids; count++) P9_DPRINTK(P9_DEBUG_9P, "<<< [%d] %x.%llx.%x\n", count, wqids[count].type, wqids[count].path, wqids[count].version); if (nwname) memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid)); else fid->qid = oldfid->qid; return fid; clunk_fid: p9_client_clunk(fid); fid = NULL; error: if (fid && (fid != oldfid)) p9_fid_destroy(fid); return ERR_PTR(err); }
struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, int clone) { int err; struct p9_fcall *tc, *rc; struct p9_client *clnt; struct p9_fid *fid; P9_DPRINTK(P9_DEBUG_9P, "fid %d nwname %d wname[0] %s\n", oldfid->fid, nwname, wnames?wnames[0]:NULL); err = 0; tc = NULL; rc = NULL; clnt = oldfid->clnt; if (clone) { fid = p9_fid_create(clnt); if (IS_ERR(fid)) { err = PTR_ERR(fid); fid = NULL; goto error; } fid->uid = oldfid->uid; } else fid = oldfid; tc = p9_create_twalk(oldfid->fid, fid->fid, nwname, wnames); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; goto error; } err = p9_conn_rpc(clnt->conn, tc, &rc); if (err) { if (rc && rc->id == P9_RWALK) goto clunk_fid; else goto error; } if (rc->params.rwalk.nwqid != nwname) { err = -ENOENT; goto clunk_fid; } if (nwname) memmove(&fid->qid, &rc->params.rwalk.wqids[rc->params.rwalk.nwqid - 1], sizeof(struct p9_qid)); else fid->qid = oldfid->qid; kfree(tc); kfree(rc); return fid; clunk_fid: kfree(tc); kfree(rc); rc = NULL; tc = p9_create_tclunk(fid->fid); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; goto error; } p9_conn_rpc(clnt->conn, tc, &rc); error: kfree(tc); kfree(rc); if (fid && (fid != oldfid)) p9_fid_destroy(fid); return ERR_PTR(err); }