⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * net/9p/clnt.c * * 9P Client * *  Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License version 2 *  as published by the Free Software Foundation. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to: *  Free Software Foundation *  51 Franklin Street, Fifth Floor *  Boston, MA  02111-1301  USA * */#include <linux/module.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/idr.h>#include <linux/mutex.h>#include <linux/sched.h>#include <linux/uaccess.h>#include <net/9p/9p.h>#include <linux/parser.h>#include <net/9p/transport.h>#include <net/9p/conn.h>#include <net/9p/client.h>static struct p9_fid *p9_fid_create(struct p9_client *clnt);static void p9_fid_destroy(struct p9_fid *fid);static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu);struct p9_client *p9_client_create(struct p9_trans *trans, int msize,								   int dotu){	int err, n;	struct p9_client *clnt;	struct p9_fcall *tc, *rc;	struct p9_str *version;	err = 0;	tc = NULL;	rc = NULL;	clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL);	if (!clnt)		return ERR_PTR(-ENOMEM);	P9_DPRINTK(P9_DEBUG_9P, "clnt %p trans %p msize %d dotu %d\n",		clnt, trans, msize, dotu);	spin_lock_init(&clnt->lock);	clnt->trans = trans;	clnt->msize = msize;	clnt->dotu = dotu;	INIT_LIST_HEAD(&clnt->fidlist);	clnt->fidpool = p9_idpool_create();	if (!clnt->fidpool) {		err = PTR_ERR(clnt->fidpool);		clnt->fidpool = NULL;		goto error;	}	clnt->conn = p9_conn_create(clnt->trans, clnt->msize, &clnt->dotu);	if (IS_ERR(clnt->conn)) {		err = PTR_ERR(clnt->conn);		clnt->conn = NULL;		goto error;	}	tc = p9_create_tversion(clnt->msize, clnt->dotu?"9P2000.u":"9P2000");	if (IS_ERR(tc)) {		err = PTR_ERR(tc);		tc = NULL;		goto error;	}	err = p9_conn_rpc(clnt->conn, tc, &rc);	if (err)		goto error;	version = &rc->params.rversion.version;	if (version->len == 8 && !memcmp(version->str, "9P2000.u", 8))		clnt->dotu = 1;	else if (version->len == 6 && !memcmp(version->str, "9P2000", 6))		clnt->dotu = 0;	else {		err = -EREMOTEIO;		goto error;	}	n = rc->params.rversion.msize;	if (n < clnt->msize)		clnt->msize = n;	kfree(tc);	kfree(rc);	return clnt;error:	kfree(tc);	kfree(rc);	p9_client_destroy(clnt);	return ERR_PTR(err);}EXPORT_SYMBOL(p9_client_create);void p9_client_destroy(struct p9_client *clnt){	struct p9_fid *fid, *fidptr;	P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);	if (clnt->conn) {		p9_conn_destroy(clnt->conn);		clnt->conn = NULL;	}	if (clnt->trans) {		clnt->trans->close(clnt->trans);		kfree(clnt->trans);		clnt->trans = NULL;	}	list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)		p9_fid_destroy(fid);	if (clnt->fidpool)		p9_idpool_destroy(clnt->fidpool);	kfree(clnt);}EXPORT_SYMBOL(p9_client_destroy);void p9_client_disconnect(struct p9_client *clnt){	P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);	clnt->trans->status = Disconnected;	p9_conn_cancel(clnt->conn, -EIO);}EXPORT_SYMBOL(p9_client_disconnect);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);}EXPORT_SYMBOL(p9_client_attach);struct p9_fid *p9_client_auth(struct p9_client *clnt, 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 uname %s aname %s\n", clnt, 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_tauth(fid->fid, 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.rauth.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);}EXPORT_SYMBOL(p9_client_auth);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);}EXPORT_SYMBOL(p9_client_walk);int p9_client_open(struct p9_fid *fid, int mode){	int err;	struct p9_fcall *tc, *rc;	struct p9_client *clnt;	P9_DPRINTK(P9_DEBUG_9P, "fid %d mode %d\n", fid->fid, mode);	err = 0;	tc = NULL;	rc = NULL;	clnt = fid->clnt;	if (fid->mode != -1)		return -EINVAL;	tc = p9_create_topen(fid->fid, mode);	if (IS_ERR(tc)) {		err = PTR_ERR(tc);		tc = NULL;		goto done;	}	err = p9_conn_rpc(clnt->conn, tc, &rc);	if (err)		goto done;	fid->mode = mode;	fid->iounit = rc->params.ropen.iounit;done:	kfree(tc);	kfree(rc);	return err;}EXPORT_SYMBOL(p9_client_open);int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,		     char *extension){	int err;	struct p9_fcall *tc, *rc;	struct p9_client *clnt;	P9_DPRINTK(P9_DEBUG_9P, "fid %d name %s perm %d mode %d\n", fid->fid,		name, perm, mode);	err = 0;	tc = NULL;	rc = NULL;	clnt = fid->clnt;	if (fid->mode != -1)		return -EINVAL;	tc = p9_create_tcreate(fid->fid, name, perm, mode, extension,							       clnt->dotu);	if (IS_ERR(tc)) {		err = PTR_ERR(tc);		tc = NULL;		goto done;	}	err = p9_conn_rpc(clnt->conn, tc, &rc);	if (err)		goto done;	fid->mode = mode;	fid->iounit = rc->params.ropen.iounit;done:	kfree(tc);	kfree(rc);	return err;}EXPORT_SYMBOL(p9_client_fcreate);int p9_client_clunk(struct p9_fid *fid){	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_tclunk(fid->fid);	if (IS_ERR(tc)) {		err = PTR_ERR(tc);		tc = NULL;		goto done;	}	err = p9_conn_rpc(clnt->conn, tc, &rc);	if (err)		goto done;	p9_fid_destroy(fid);done:	kfree(tc);	kfree(rc);	return err;}EXPORT_SYMBOL(p9_client_clunk);int p9_client_remove(struct p9_fid *fid){	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_tremove(fid->fid);	if (IS_ERR(tc)) {		err = PTR_ERR(tc);		tc = NULL;		goto done;	}	err = p9_conn_rpc(clnt->conn, tc, &rc);	if (err)		goto done;	p9_fid_destroy(fid);done:	kfree(tc);	kfree(rc);	return err;}EXPORT_SYMBOL(p9_client_remove);int p9_client_read(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 %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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -