static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq) { struct p9_req_t *req; int16_t oldtag; int err; err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1); if (err) return err; P9_DPRINTK(P9_DEBUG_9P, ">>> TFLUSH tag %d\n", oldtag); req = p9_client_rpc(c, P9_TFLUSH, "w", oldtag); if (IS_ERR(req)) return PTR_ERR(req); /* if we haven't received a response for oldreq, remove it from the list. */ spin_lock(&c->lock); if (oldreq->status == REQ_STATUS_FLSH) list_del(&oldreq->req_list); spin_unlock(&c->lock); p9_free_req(c, req); return 0; }
int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) { int err; struct p9_req_t *req; struct p9_client *clnt; P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid); P9_DPRINTK(P9_DEBUG_9P, " sz=%x type=%x dev=%x qid=%x.%llx.%x\n" " mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n" " name=%s uid=%s gid=%s muid=%s extension=(%s)\n" " uid=%d gid=%d n_muid=%d\n", wst->size, wst->type, wst->dev, wst->qid.type, wst->qid.path, wst->qid.version, wst->mode, wst->atime, wst->mtime, wst->length, wst->name, wst->uid, wst->gid, wst->muid, wst->extension, wst->n_uid, wst->n_gid, wst->n_muid); err = 0; clnt = fid->clnt; req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, 0, wst); if (IS_ERR(req)) { err = PTR_ERR(req); goto error; } P9_DPRINTK(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid); p9_free_req(clnt, req); error: return err; }
int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, u64 offset, u32 count) { int err, rsize, total; struct p9_client *clnt; struct p9_req_t *req; P9_DPRINTK(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d\n", fid->fid, (long long unsigned) offset, count); err = 0; clnt = fid->clnt; total = 0; rsize = fid->iounit; if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) rsize = clnt->msize - P9_IOHDRSZ; if (count < rsize) rsize = count; if (data) req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid, offset, rsize, data); else req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid, offset, rsize, udata); if (IS_ERR(req)) { err = PTR_ERR(req); goto error; } err = p9pdu_readf(req->rc, clnt->dotu, "d", &count); if (err) { p9pdu_dump(1, req->rc); goto free_and_error; } P9_DPRINTK(P9_DEBUG_9P, "<<< RWRITE count %d\n", count); p9_free_req(clnt, req); return count; free_and_error: p9_free_req(clnt, req); error: return err; }
int p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, u32 count) { int err, rsize, total; struct p9_client *clnt; struct p9_req_t *req; char *dataptr; P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", fid->fid, (long long unsigned) offset, count); err = 0; clnt = fid->clnt; total = 0; rsize = fid->iounit; if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) rsize = clnt->msize - P9_IOHDRSZ; if (count < rsize) rsize = count; req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, rsize); if (IS_ERR(req)) { err = PTR_ERR(req); goto error; } err = p9pdu_readf(req->rc, clnt->dotu, "D", &count, &dataptr); if (err) { p9pdu_dump(1, req->rc); goto free_and_error; } P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count); if (data) { memmove(data, dataptr, count); data += count; } if (udata) { err = copy_to_user(udata, dataptr, count); if (err) { err = -EFAULT; goto free_and_error; } } p9_free_req(clnt, req); return count; free_and_error: p9_free_req(clnt, req); error: return 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_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_wstat *p9_client_stat(struct p9_fid *fid) { int err; struct p9_client *clnt; struct p9_wstat *ret = kmalloc(sizeof(struct p9_wstat), GFP_KERNEL); struct p9_req_t *req; u16 ignored; P9_DPRINTK(P9_DEBUG_9P, ">>> TSTAT fid %d\n", fid->fid); if (!ret) return ERR_PTR(-ENOMEM); err = 0; clnt = fid->clnt; req = p9_client_rpc(clnt, P9_TSTAT, "d", fid->fid); if (IS_ERR(req)) { err = PTR_ERR(req); goto error; } err = p9pdu_readf(req->rc, clnt->dotu, "wS", &ignored, ret); if (err) { p9pdu_dump(1, req->rc); p9_free_req(clnt, req); goto error; } P9_DPRINTK(P9_DEBUG_9P, "<<< RSTAT sz=%x type=%x dev=%x qid=%x.%llx.%x\n" "<<< mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n" "<<< name=%s uid=%s gid=%s muid=%s extension=(%s)\n" "<<< uid=%d gid=%d n_muid=%d\n", ret->size, ret->type, ret->dev, ret->qid.type, (unsigned long long)ret->qid.path, ret->qid.version, ret->mode, ret->atime, ret->mtime, (unsigned long long)ret->length, ret->name, ret->uid, ret->gid, ret->muid, ret->extension, ret->n_uid, ret->n_gid, ret->n_muid); p9_free_req(clnt, req); return ret; error: kfree(ret); return ERR_PTR(err); }
int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode, char *extension) { int err; struct p9_client *clnt; struct p9_req_t *req; struct p9_qid qid; int iounit; P9_DPRINTK(P9_DEBUG_9P, ">>> TCREATE fid %d name %s perm %d mode %d\n", fid->fid, name, perm, mode); err = 0; clnt = fid->clnt; if (fid->mode != -1) return -EINVAL; req = p9_client_rpc(clnt, P9_TCREATE, "dsdb?s", fid->fid, name, perm, mode, extension); if (IS_ERR(req)) { err = PTR_ERR(req); goto error; } err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit); if (err) { p9pdu_dump(1, req->rc); goto free_and_error; } P9_DPRINTK(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n", qid.type, (unsigned long long)qid.path, qid.version, iounit); fid->mode = mode; fid->iounit = iounit; free_and_error: p9_free_req(clnt, req); error: return err; }
static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq) { struct p9_req_t *req; int16_t oldtag; int err; err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1); if (err) return err; P9_DPRINTK(P9_DEBUG_9P, ">>> TFLUSH tag %d\n", oldtag); req = p9_client_rpc(c, P9_TFLUSH, "w", oldtag); if (IS_ERR(req)) return PTR_ERR(req); req->flush_tag = oldtag; /* we don't free anything here because RPC isn't complete */ return 0; }
int p9_client_version(struct p9_client *c) { int err = 0; struct p9_req_t *req; char *version; int msize; P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d extended %d\n", c->msize, c->dotu); req = p9_client_rpc(c, P9_TVERSION, "ds", c->msize, c->dotu ? "9P2000.u" : "9P2000"); if (IS_ERR(req)) return PTR_ERR(req); err = p9pdu_readf(req->rc, c->dotu, "ds", &msize, &version); if (err) { P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err); p9pdu_dump(1, req->rc); goto error; } P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version); if (!memcmp(version, "9P2000.u", 8)) c->dotu = 1; else if (!memcmp(version, "9P2000", 6)) c->dotu = 0; else { err = -EREMOTEIO; goto error; } if (msize < c->msize) c->msize = msize; error: kfree(version); p9_free_req(c, req); return err; }
int p9_client_open(struct p9_fid *fid, int mode) { int err; struct p9_client *clnt; struct p9_req_t *req; struct p9_qid qid; int iounit; P9_DPRINTK(P9_DEBUG_9P, ">>> TOPEN fid %d mode %d\n", fid->fid, mode); err = 0; clnt = fid->clnt; if (fid->mode != -1) return -EINVAL; req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode); if (IS_ERR(req)) { err = PTR_ERR(req); goto error; } err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit); if (err) { p9pdu_dump(1, req->rc); goto free_and_error; } P9_DPRINTK(P9_DEBUG_9P, "<<< ROPEN qid %x.%llx.%x iounit %x\n", qid.type, (unsigned long long)qid.path, qid.version, iounit); fid->mode = mode; fid->iounit = iounit; free_and_error: p9_free_req(clnt, req); error: return err; }
int p9_client_remove(struct p9_fid *fid) { int err; struct p9_client *clnt; struct p9_req_t *req; P9_DPRINTK(P9_DEBUG_9P, ">>> TREMOVE fid %d\n", fid->fid); err = 0; clnt = fid->clnt; req = p9_client_rpc(clnt, P9_TREMOVE, "d", fid->fid); if (IS_ERR(req)) { err = PTR_ERR(req); goto error; } P9_DPRINTK(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid); p9_free_req(clnt, req); p9_fid_destroy(fid); error: return 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); }