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

📄 client.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		}		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 + -