struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, int dotu) { int size, statsz; struct p9_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; statsz = p9_size_wstat(wstat, dotu); size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */ fc = p9_create_common(bufp, size, P9_TWSTAT); if (IS_ERR(fc)) goto error; p9_put_int32(bufp, fid, &fc->params.twstat.fid); buf_put_int16(bufp, statsz + 2); p9_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, dotu); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, const char __user *data) { int size, err; struct p9_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; /* fid[4] offset[8] count[4] data[count] */ size = 4 + 8 + 4 + count; fc = p9_create_common(bufp, size, P9_TWRITE); if (IS_ERR(fc)) goto error; p9_put_int32(bufp, fid, &fc->params.twrite.fid); p9_put_int64(bufp, offset, &fc->params.twrite.offset); p9_put_int32(bufp, count, &fc->params.twrite.count); err = p9_put_user_data(bufp, data, count, &fc->params.twrite.data); if (err) { kfree(fc); fc = ERR_PTR(err); goto error; } if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, char *extension, int dotu) { int size; struct p9_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; /* fid[4] name[s] perm[4] mode[1] */ size = 4 + 2 + strlen(name) + 4 + 1; if (dotu) { size += 2 + /* extension[s] */ (extension == NULL ? 0 : strlen(extension)); } fc = p9_create_common(bufp, size, P9_TCREATE); if (IS_ERR(fc)) goto error; p9_put_int32(bufp, fid, &fc->params.tcreate.fid); p9_put_str(bufp, name, &fc->params.tcreate.name); p9_put_int32(bufp, perm, &fc->params.tcreate.perm); p9_put_int8(bufp, mode, &fc->params.tcreate.mode); if (dotu) p9_put_str(bufp, extension, &fc->params.tcreate.extension); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, char *extension, int extended) { int size; struct v9fs_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */ if (extended && extension!=NULL) size += 2 + strlen(extension); /* extension[s] */ fc = v9fs_create_common(bufp, size, TCREATE); if (IS_ERR(fc)) goto error; v9fs_put_int32(bufp, fid, &fc->params.tcreate.fid); v9fs_put_str(bufp, name, &fc->params.tcreate.name); v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm); v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode); if (extended) v9fs_put_str(bufp, extension, &fc->params.tcreate.extension); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
static void buf_get_str(struct cbuf *buf, struct p9_str *vstr) { vstr->len = buf_get_int16(buf); if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) { vstr->str = buf->p; buf->p += vstr->len; } else { vstr->len = 0; vstr->str = NULL; } }
int p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, int dotu) { struct cbuf buffer; struct cbuf *bufp = &buffer; unsigned char *p; buf_init(bufp, buf, buflen); p = bufp->p; buf_get_stat(bufp, stat, dotu); if (buf_check_overflow(bufp)) return 0; else return bufp->p - p; }
struct p9_fcall *p9_create_tstat(u32 fid) { int size; struct p9_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; size = 4; /* fid[4] */ fc = p9_create_common(bufp, size, P9_TSTAT); if (IS_ERR(fc)) goto error; p9_put_int32(bufp, fid, &fc->params.tstat.fid); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct p9_fcall *p9_create_tflush(u16 oldtag) { int size; struct p9_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; size = 2; /* oldtag[2] */ fc = p9_create_common(bufp, size, P9_TFLUSH); if (IS_ERR(fc)) goto error; p9_put_int16(bufp, oldtag, &fc->params.tflush.oldtag); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct v9fs_fcall *v9fs_create_tremove(u32 fid) { int size; struct v9fs_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; size = 4; /* fid[4] */ fc = v9fs_create_common(bufp, size, TREMOVE); if (IS_ERR(fc)) goto error; v9fs_put_int32(bufp, fid, &fc->params.tremove.fid); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct p9_fcall *p9_create_topen(u32 fid, u8 mode) { int size; struct p9_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; size = 4 + 1; /* fid[4] mode[1] */ fc = p9_create_common(bufp, size, P9_TOPEN); if (IS_ERR(fc)) goto error; p9_put_int32(bufp, fid, &fc->params.topen.fid); p9_put_int8(bufp, mode, &fc->params.topen.mode); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct p9_fcall *p9_create_tversion(u32 msize, char *version) { int size; struct p9_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; size = 4 + 2 + strlen(version); /* msize[4] version[s] */ fc = p9_create_common(bufp, size, P9_TVERSION); if (IS_ERR(fc)) goto error; p9_put_int32(bufp, msize, &fc->params.tversion.msize); p9_put_str(bufp, version, &fc->params.tversion.version); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count) { int size; struct p9_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; size = 4 + 8 + 4; /* fid[4] offset[8] count[4] */ fc = p9_create_common(bufp, size, P9_TREAD); if (IS_ERR(fc)) goto error; p9_put_int32(bufp, fid, &fc->params.tread.fid); p9_put_int64(bufp, offset, &fc->params.tread.offset); p9_put_int32(bufp, count, &fc->params.tread.count); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname) { int size; struct v9fs_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; size = 4 + 2 + strlen(uname) + 2 + strlen(aname); /* afid[4] uname[s] aname[s] */ fc = v9fs_create_common(bufp, size, TAUTH); if (IS_ERR(fc)) goto error; v9fs_put_int32(bufp, afid, &fc->params.tauth.afid); v9fs_put_str(bufp, uname, &fc->params.tauth.uname); v9fs_put_str(bufp, aname, &fc->params.tauth.aname); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname, char **wnames) { int i, size; struct p9_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; if (nwname > P9_MAXWELEM) { P9_DPRINTK(P9_DEBUG_ERROR, "nwname > %d\n", P9_MAXWELEM); return NULL; } size = 4 + 4 + 2; /* fid[4] newfid[4] nwname[2] ... */ for (i = 0; i < nwname; i++) { size += 2 + strlen(wnames[i]); /* wname[s] */ } fc = p9_create_common(bufp, size, P9_TWALK); if (IS_ERR(fc)) goto error; p9_put_int32(bufp, fid, &fc->params.twalk.fid); p9_put_int32(bufp, newfid, &fc->params.twalk.newfid); p9_put_int16(bufp, nwname, &fc->params.twalk.nwname); for (i = 0; i < nwname; i++) { p9_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]); } if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname, u32 n_uname, int dotu) { int size; struct p9_fcall *fc; struct cbuf buffer; struct cbuf *bufp = &buffer; /* afid[4] uname[s] aname[s] */ size = 4 + 2 + 2; if (uname) size += strlen(uname); if (aname) size += strlen(aname); if (dotu) size += 4; /* n_uname */ fc = p9_create_common(bufp, size, P9_TAUTH); if (IS_ERR(fc)) goto error; p9_put_int32(bufp, afid, &fc->params.tauth.afid); p9_put_str(bufp, uname, &fc->params.tauth.uname); p9_put_str(bufp, aname, &fc->params.tauth.aname); if (dotu) p9_put_int32(bufp, n_uname, &fc->params.tauth.n_uname); if (buf_check_overflow(bufp)) { kfree(fc); fc = ERR_PTR(-ENOMEM); } error: return fc; }
int p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *rcall, int dotu) { struct cbuf buffer; struct cbuf *bufp = &buffer; int i = 0; buf_init(bufp, buf, buflen); rcall->size = buf_get_int32(bufp); rcall->id = buf_get_int8(bufp); rcall->tag = buf_get_int16(bufp); P9_DPRINTK(P9_DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, rcall->id, rcall->tag); switch (rcall->id) { default: P9_EPRINTK(KERN_ERR, "unknown message type: %d\n", rcall->id); return -EPROTO; case P9_RVERSION: rcall->params.rversion.msize = buf_get_int32(bufp); buf_get_str(bufp, &rcall->params.rversion.version); break; case P9_RFLUSH: break; case P9_RATTACH: rcall->params.rattach.qid.type = buf_get_int8(bufp); rcall->params.rattach.qid.version = buf_get_int32(bufp); rcall->params.rattach.qid.path = buf_get_int64(bufp); break; case P9_RWALK: rcall->params.rwalk.nwqid = buf_get_int16(bufp); if (rcall->params.rwalk.nwqid > P9_MAXWELEM) { P9_EPRINTK(KERN_ERR, "Rwalk with more than %d qids: %d\n", P9_MAXWELEM, rcall->params.rwalk.nwqid); return -EPROTO; } for (i = 0; i < rcall->params.rwalk.nwqid; i++) buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]); break; case P9_ROPEN: buf_get_qid(bufp, &rcall->params.ropen.qid); rcall->params.ropen.iounit = buf_get_int32(bufp); break; case P9_RCREATE: buf_get_qid(bufp, &rcall->params.rcreate.qid); rcall->params.rcreate.iounit = buf_get_int32(bufp); break; case P9_RREAD: rcall->params.rread.count = buf_get_int32(bufp); rcall->params.rread.data = bufp->p; buf_check_size(bufp, rcall->params.rread.count); break; case P9_RWRITE: rcall->params.rwrite.count = buf_get_int32(bufp); break; case P9_RCLUNK: break; case P9_RREMOVE: break; case P9_RSTAT: buf_get_int16(bufp); buf_get_stat(bufp, &rcall->params.rstat.stat, dotu); break; case P9_RWSTAT: break; case P9_RERROR: buf_get_str(bufp, &rcall->params.rerror.error); if (dotu) rcall->params.rerror.errno = buf_get_int16(bufp); break; } if (buf_check_overflow(bufp)) { P9_DPRINTK(P9_DEBUG_ERROR, "buffer overflow\n"); return -EIO; } return bufp->p - bufp->sp; }