📄 client.c
字号:
} err = p9_conn_rpc(clnt->conn, tc, &rc); if (err) goto error; n = rc->params.rread.count; if (n > count) n = count; memmove(data, rc->params.rread.data, n); count -= n; data += n; offset += n; total += n; kfree(tc); tc = NULL; kfree(rc); rc = NULL; } while (count > 0 && n == rsize); return total;error: kfree(tc); kfree(rc); return err;}EXPORT_SYMBOL(p9_client_read);int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count){ int err, n, rsize, total; struct p9_fcall *tc, *rc; struct p9_client *clnt; P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, (long long unsigned) offset, count); err = 0; tc = NULL; rc = NULL; clnt = fid->clnt; total = 0; rsize = fid->iounit; if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) rsize = clnt->msize - P9_IOHDRSZ; do { if (count < rsize) rsize = count; tc = p9_create_twrite(fid->fid, offset, rsize, data); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; goto error; } err = p9_conn_rpc(clnt->conn, tc, &rc); if (err) goto error; n = rc->params.rread.count; count -= n; data += n; offset += n; total += n; kfree(tc); tc = NULL; kfree(rc); rc = NULL; } while (count > 0); return total;error: kfree(tc); kfree(rc); return err;}EXPORT_SYMBOL(p9_client_write);intp9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, u32 count){ int err, n, rsize, total; struct p9_fcall *tc, *rc; struct p9_client *clnt; P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, (long long unsigned) offset, count); err = 0; tc = NULL; rc = NULL; clnt = fid->clnt; total = 0; rsize = fid->iounit; if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) rsize = clnt->msize - P9_IOHDRSZ; do { if (count < rsize) rsize = count; tc = p9_create_tread(fid->fid, offset, rsize); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; goto error; } err = p9_conn_rpc(clnt->conn, tc, &rc); if (err) goto error; n = rc->params.rread.count; if (n > count) n = count; err = copy_to_user(data, rc->params.rread.data, n); if (err) { err = -EFAULT; goto error; } count -= n; data += n; offset += n; total += n; kfree(tc); tc = NULL; kfree(rc); rc = NULL; } while (count > 0 && n == rsize); return total;error: kfree(tc); kfree(rc); return err;}EXPORT_SYMBOL(p9_client_uread);intp9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset, u32 count){ int err, n, rsize, total; struct p9_fcall *tc, *rc; struct p9_client *clnt; P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, (long long unsigned) offset, count); err = 0; tc = NULL; rc = NULL; clnt = fid->clnt; total = 0; rsize = fid->iounit; if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) rsize = clnt->msize - P9_IOHDRSZ; do { if (count < rsize) rsize = count; tc = p9_create_twrite_u(fid->fid, offset, rsize, data); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; goto error; } err = p9_conn_rpc(clnt->conn, tc, &rc); if (err) goto error; n = rc->params.rread.count; count -= n; data += n; offset += n; total += n; kfree(tc); tc = NULL; kfree(rc); rc = NULL; } while (count > 0); return total;error: kfree(tc); kfree(rc); return err;}EXPORT_SYMBOL(p9_client_uwrite);int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count){ int n, total; P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, (long long unsigned) offset, count); n = 0; total = 0; while (count) { n = p9_client_read(fid, data, offset, count); if (n <= 0) break; data += n; offset += n; count -= n; total += n; } if (n < 0) total = n; return total;}EXPORT_SYMBOL(p9_client_readn);struct p9_stat *p9_client_stat(struct p9_fid *fid){ int err; struct p9_fcall *tc, *rc; struct p9_client *clnt; struct p9_stat *ret; P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); err = 0; tc = NULL; rc = NULL; ret = NULL; clnt = fid->clnt; tc = p9_create_tstat(fid->fid); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; goto error; } err = p9_conn_rpc(clnt->conn, tc, &rc); if (err) goto error; ret = p9_clone_stat(&rc->params.rstat.stat, clnt->dotu); if (IS_ERR(ret)) { err = PTR_ERR(ret); ret = NULL; goto error; } kfree(tc); kfree(rc); return ret;error: kfree(tc); kfree(rc); kfree(ret); return ERR_PTR(err);}EXPORT_SYMBOL(p9_client_stat);int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst){ int err; struct p9_fcall *tc, *rc; struct p9_client *clnt; P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); err = 0; tc = NULL; rc = NULL; clnt = fid->clnt; tc = p9_create_twstat(fid->fid, wst, clnt->dotu); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; goto done; } err = p9_conn_rpc(clnt->conn, tc, &rc);done: kfree(tc); kfree(rc); return err;}EXPORT_SYMBOL(p9_client_wstat);struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset){ int err, n, m; struct p9_fcall *tc, *rc; struct p9_client *clnt; struct p9_stat st, *ret; P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu\n", fid->fid, (long long unsigned) offset); err = 0; tc = NULL; rc = NULL; ret = NULL; clnt = fid->clnt; /* if the offset is below or above the current response, free it */ if (offset < fid->rdir_fpos || (fid->rdir_fcall && offset >= fid->rdir_fpos+fid->rdir_fcall->params.rread.count)) { fid->rdir_pos = 0; if (fid->rdir_fcall) fid->rdir_fpos += fid->rdir_fcall->params.rread.count; kfree(fid->rdir_fcall); fid->rdir_fcall = NULL; if (offset < fid->rdir_fpos) fid->rdir_fpos = 0; } if (!fid->rdir_fcall) { n = fid->iounit; if (!n || n > clnt->msize-P9_IOHDRSZ) n = clnt->msize - P9_IOHDRSZ; while (1) { if (fid->rdir_fcall) { fid->rdir_fpos += fid->rdir_fcall->params.rread.count; kfree(fid->rdir_fcall); fid->rdir_fcall = NULL; } tc = p9_create_tread(fid->fid, fid->rdir_fpos, n); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; goto error; } err = p9_conn_rpc(clnt->conn, tc, &rc); if (err) goto error; n = rc->params.rread.count; if (n == 0) goto done; fid->rdir_fcall = rc; rc = NULL; if (offset >= fid->rdir_fpos && offset < fid->rdir_fpos+n) break; } fid->rdir_pos = 0; } m = offset - fid->rdir_fpos; if (m < 0) goto done; n = p9_deserialize_stat(fid->rdir_fcall->params.rread.data + m, fid->rdir_fcall->params.rread.count - m, &st, clnt->dotu); if (!n) { err = -EIO; goto error; } fid->rdir_pos += n; st.size = n; ret = p9_clone_stat(&st, clnt->dotu); if (IS_ERR(ret)) { err = PTR_ERR(ret); ret = NULL; goto error; }done: kfree(tc); kfree(rc); return ret;error: kfree(tc); kfree(rc); kfree(ret); return ERR_PTR(err);}EXPORT_SYMBOL(p9_client_dirread);static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu){ int n; char *p; struct p9_stat *ret; n = sizeof(struct p9_stat) + st->name.len + st->uid.len + st->gid.len + st->muid.len; if (dotu) n += st->extension.len; ret = kmalloc(n, GFP_KERNEL); if (!ret) return ERR_PTR(-ENOMEM); memmove(ret, st, sizeof(struct p9_stat)); p = ((char *) ret) + sizeof(struct p9_stat); memmove(p, st->name.str, st->name.len); p += st->name.len; memmove(p, st->uid.str, st->uid.len); p += st->uid.len; memmove(p, st->gid.str, st->gid.len); p += st->gid.len; memmove(p, st->muid.str, st->muid.len); p += st->muid.len; if (dotu) { memmove(p, st->extension.str, st->extension.len); p += st->extension.len; } return ret;}static struct p9_fid *p9_fid_create(struct p9_client *clnt){ int err; struct p9_fid *fid; P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL); if (!fid) return ERR_PTR(-ENOMEM); fid->fid = p9_idpool_get(clnt->fidpool); if (fid->fid < 0) { err = -ENOSPC; goto error; } memset(&fid->qid, 0, sizeof(struct p9_qid)); fid->mode = -1; fid->rdir_fpos = 0; fid->rdir_pos = 0; fid->rdir_fcall = NULL; fid->uid = current->fsuid; fid->clnt = clnt; fid->aux = NULL; spin_lock(&clnt->lock); list_add(&fid->flist, &clnt->fidlist); spin_unlock(&clnt->lock); return fid;error: kfree(fid); return ERR_PTR(err);}static void p9_fid_destroy(struct p9_fid *fid){ struct p9_client *clnt; P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); clnt = fid->clnt; p9_idpool_put(fid->fid, clnt->fidpool); spin_lock(&clnt->lock); list_del(&fid->flist); spin_unlock(&clnt->lock); kfree(fid->rdir_fcall); kfree(fid);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -