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

📄 nfs3xdr.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 2 页
字号:
	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readdirres_sz) << 2;	buflen = req->rq_rvec[0].iov_len;	req->rq_rvec[0].iov_len  = replen;	req->rq_rvec[1].iov_base = args->buffer;	req->rq_rvec[1].iov_len  = args->bufsiz;	req->rq_rvec[2].iov_base = (u8 *) req->rq_rvec[0].iov_base + replen;	req->rq_rvec[2].iov_len  = buflen - replen;	req->rq_rlen = buflen + args->bufsiz;	req->rq_rnr += 2;	return 0;}/* * Decode the result of a readdir call. * We just check for syntactical correctness. */static intnfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res){	struct iovec	*iov = req->rq_rvec;	int		hdrlen;	int		status, nr;	unsigned int	len;	u32		*entry, *end;	status = ntohl(*p++);	/* Decode post_op_attrs */	p = xdr_decode_post_op_attr(p, res->dir_attr);	if (status)		return -nfs_stat_to_errno(status);	/* Decode verifier cookie */	if (res->verf) {		res->verf[0] = *p++;		res->verf[1] = *p++;	} else {		p += 2;	}	hdrlen = (u8 *) p - (u8 *) iov->iov_base;	if (iov->iov_len > hdrlen) {		dprintk("NFS: READDIR header is short. iovec will be shifted.\n");		xdr_shift_iovec(iov, req->rq_rnr, iov->iov_len - hdrlen);	}	p   = (u32 *) iov[1].iov_base;	end = (u32 *) ((u8 *) p + iov[1].iov_len);	for (nr = 0; *p++; nr++) {		entry = p - 1;		if (p + 3 > end)			goto short_pkt;		p += 2;				/* inode # */		len = ntohl(*p++);		/* string length */		p += XDR_QUADLEN(len) + 2;	/* name + cookie */		if (len > NFS3_MAXNAMLEN) {			printk(KERN_WARNING "NFS: giant filename in readdir (len %x)!\n",						len);			return -errno_NFSERR_IO;		}		if (res->plus) {			/* post_op_attr */			if (p > end)				goto short_pkt;			if (*p++) {				p += 21;				if (p > end)					goto short_pkt;			}			/* post_op_fh3 */			if (*p++) {				if (p > end)					goto short_pkt;				len = ntohl(*p++);				if (len > NFS3_FHSIZE) {					printk(KERN_WARNING "NFS: giant filehandle in "						"readdir (len %x)!\n", len);					return -errno_NFSERR_IO;				}				p += XDR_QUADLEN(len);			}		}		if (p + 2 > end)			goto short_pkt;	}	return nr; short_pkt:	printk(KERN_NOTICE "NFS: short packet in readdir reply!\n");	/* truncate listing */	entry[0] = entry[1] = 0;	return nr;}u32 *nfs3_decode_dirent(u32 *p, struct nfs_entry *entry, int plus){	struct nfs_entry old = *entry;	if (!*p++) {		if (!*p)			return ERR_PTR(-EAGAIN);		entry->eof = 1;		return ERR_PTR(-EBADCOOKIE);	}	p = xdr_decode_hyper(p, &entry->ino);	entry->len  = ntohl(*p++);	entry->name = (const char *) p;	p += XDR_QUADLEN(entry->len);	entry->prev_cookie = entry->cookie;	p = xdr_decode_hyper(p, &entry->cookie);	if (plus) {		p = xdr_decode_post_op_attr(p, &entry->fattr);		/* In fact, a post_op_fh3: */		if (*p++) {			p = xdr_decode_fhandle(p, &entry->fh);			/* Ugh -- server reply was truncated */			if (p == NULL) {				dprintk("NFS: FH truncated\n");				*entry = old;				return ERR_PTR(-EAGAIN);			}		} else {			/* If we don't get a file handle, the attrs			 * aren't worth a lot. */			entry->fattr.valid = 0;		}	}	entry->eof = !p[0] && p[1];	return p;}/* * Encode COMMIT arguments */static intnfs3_xdr_commitargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args){	p = xdr_encode_fhandle(p, args->fh);	p = xdr_encode_hyper(p, args->offset);	*p++ = htonl(args->count);	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);	return 0;}/* * NFS XDR decode functions *//* * Decode void reply */static intnfs3_xdr_dec_void(struct rpc_rqst *req, u32 *p, void *dummy){	return 0;}/* * Decode attrstat reply. */static intnfs3_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr){	int	status;	if ((status = ntohl(*p++)))		return -nfs_stat_to_errno(status);	xdr_decode_fattr(p, fattr);	return 0;}/* * Decode status+wcc_data reply * SATTR, REMOVE, RMDIR */static intnfs3_xdr_wccstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr){	int	status;	if ((status = ntohl(*p++)))		status = -nfs_stat_to_errno(status);	xdr_decode_wcc_data(p, fattr);	return status;}/* * Decode LOOKUP reply */static intnfs3_xdr_lookupres(struct rpc_rqst *req, u32 *p, struct nfs3_diropres *res){	int	status;	if ((status = ntohl(*p++))) {		status = -nfs_stat_to_errno(status);	} else {		if (!(p = xdr_decode_fhandle(p, res->fh)))			return -errno_NFSERR_IO;		p = xdr_decode_post_op_attr(p, res->fattr);	}	xdr_decode_post_op_attr(p, res->dir_attr);	return status;}/* * Decode ACCESS reply */static intnfs3_xdr_accessres(struct rpc_rqst *req, u32 *p, struct nfs3_accessres *res){	int	status = ntohl(*p++);	p = xdr_decode_post_op_attr(p, res->fattr);	if (status)		return -nfs_stat_to_errno(status);	res->access = ntohl(*p++);	return 0;}static intnfs3_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_readlinkargs *args){	struct rpc_task *task = req->rq_task;	struct rpc_auth *auth = task->tk_auth;	int		buflen, replen;	p = xdr_encode_fhandle(p, args->fh);	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readlinkres_sz) << 2;	buflen = req->rq_rvec[0].iov_len;	req->rq_rvec[0].iov_len  = replen;	req->rq_rvec[1].iov_base = args->buffer;	req->rq_rvec[1].iov_len  = args->bufsiz;	req->rq_rvec[2].iov_base = (u8 *) req->rq_rvec[0].iov_base + replen;	req->rq_rvec[2].iov_len  = buflen - replen;	req->rq_rlen = buflen + args->bufsiz;	req->rq_rnr += 2;	return 0;}/* * Decode READLINK reply */static intnfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs3_readlinkres *res){	struct iovec	*iov = req->rq_rvec;	int		hdrlen;	u32	*strlen;	char	*string;	int	status;	unsigned int len;	status = ntohl(*p++);	p = xdr_decode_post_op_attr(p, res->fattr);	if (status != 0)		return -nfs_stat_to_errno(status);	hdrlen = (u8 *) p - (u8 *) iov->iov_base;	if (iov->iov_len > hdrlen) {		dprintk("NFS: READLINK header is short. iovec will be shifted.\n");		xdr_shift_iovec(iov, req->rq_rnr, iov->iov_len - hdrlen);	}	strlen = (u32*)res->buffer;	/* Convert length of symlink */	len = ntohl(*strlen);	if (len > res->bufsiz - 5)		len = res->bufsiz - 5;	*strlen = len;	/* NULL terminate the string we got */	string = (char *)(strlen + 1);	string[len] = 0;	return 0;}/* * Decode READ reply */static intnfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res){	struct iovec *iov = req->rq_rvec;	int	status, count, ocount, recvd, hdrlen;	status = ntohl(*p++);	p = xdr_decode_post_op_attr(p, res->fattr);	if (status != 0)		return -nfs_stat_to_errno(status);	/* Decode reply could and EOF flag. NFSv3 is somewhat redundant	 * in that it puts the count both in the res struct and in the	 * opaque data count. */	count    = ntohl(*p++);	res->eof = ntohl(*p++);	ocount   = ntohl(*p++);	if (ocount != count) {		printk(KERN_WARNING "NFS: READ count doesn't match RPC opaque count.\n");		return -errno_NFSERR_IO;	}	hdrlen = (u8 *) p - (u8 *) iov->iov_base;	if (iov->iov_len > hdrlen) {		dprintk("NFS: READ header is short. iovec will be shifted.\n");		xdr_shift_iovec(iov, req->rq_rnr, iov->iov_len - hdrlen);	}	recvd = req->rq_rlen - hdrlen;	if (count > recvd) {		printk(KERN_WARNING "NFS: server cheating in read reply: "			"count %d > recvd %d\n", count, recvd);		count = recvd;	}	if (count < res->count) {		xdr_zero_iovec(iov+1, req->rq_rnr-2, res->count - count);		res->count = count;	}	return count;}/* * Decode WRITE response */static intnfs3_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res){	int	status;	status = ntohl(*p++);	p = xdr_decode_wcc_data(p, res->fattr);	if (status != 0)		return -nfs_stat_to_errno(status);	res->count = ntohl(*p++);	res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);	res->verf->verifier[0] = *p++;	res->verf->verifier[1] = *p++;	return res->count;}/* * Decode a CREATE response */static intnfs3_xdr_createres(struct rpc_rqst *req, u32 *p, struct nfs3_diropres *res){	int	status;	status = ntohl(*p++);	if (status == 0) {		if (*p++) {			if (!(p = xdr_decode_fhandle(p, res->fh)))				return -errno_NFSERR_IO;			p = xdr_decode_post_op_attr(p, res->fattr);		} else {			memset(res->fh, 0, sizeof(*res->fh));			/* Do decode post_op_attr but set it to NULL */			p = xdr_decode_post_op_attr(p, res->fattr);			res->fattr->valid = 0;		}	} else {		status = -nfs_stat_to_errno(status);	}	p = xdr_decode_wcc_data(p, res->dir_attr);	return status;}/* * Decode RENAME reply */static intnfs3_xdr_renameres(struct rpc_rqst *req, u32 *p, struct nfs3_renameres *res){	int	status;	if ((status = ntohl(*p++)) != 0)		status = -nfs_stat_to_errno(status);	p = xdr_decode_wcc_data(p, res->fromattr);	p = xdr_decode_wcc_data(p, res->toattr);	return status;}/* * Decode LINK reply */static intnfs3_xdr_linkres(struct rpc_rqst *req, u32 *p, struct nfs3_linkres *res){	int	status;	if ((status = ntohl(*p++)) != 0)		status = -nfs_stat_to_errno(status);	p = xdr_decode_post_op_attr(p, res->fattr);	p = xdr_decode_wcc_data(p, res->dir_attr);	return status;}/* * Decode FSSTAT reply */static intnfs3_xdr_fsstatres(struct rpc_rqst *req, u32 *p, struct nfs_fsinfo *res){	struct nfs_fattr dummy;	int		status;	status = ntohl(*p++);	p = xdr_decode_post_op_attr(p, &dummy);	if (status != 0)		return -nfs_stat_to_errno(status);	p = xdr_decode_hyper(p, &res->tbytes);	p = xdr_decode_hyper(p, &res->fbytes);	p = xdr_decode_hyper(p, &res->abytes);	p = xdr_decode_hyper(p, &res->tfiles);	p = xdr_decode_hyper(p, &res->ffiles);	p = xdr_decode_hyper(p, &res->afiles);	/* ignore invarsec */	return 0;}/* * Decode FSINFO reply */static intnfs3_xdr_fsinfores(struct rpc_rqst *req, u32 *p, struct nfs_fsinfo *res){	struct nfs_fattr dummy;	int		status;	status = ntohl(*p++);	p = xdr_decode_post_op_attr(p, &dummy);	if (status != 0)		return -nfs_stat_to_errno(status);	res->rtmax  = ntohl(*p++);	res->rtpref = ntohl(*p++);	res->rtmult = ntohl(*p++);	res->wtmax  = ntohl(*p++);	res->wtpref = ntohl(*p++);	res->wtmult = ntohl(*p++);	res->dtpref = ntohl(*p++);	p = xdr_decode_hyper(p, &res->maxfilesize);	/* ignore time_delta and properties */	return 0;}/* * Decode PATHCONF reply */static intnfs3_xdr_pathconfres(struct rpc_rqst *req, u32 *p, struct nfs_fsinfo *res){	struct nfs_fattr dummy;	int		status;	status = ntohl(*p++);	p = xdr_decode_post_op_attr(p, &dummy);	if (status != 0)		return -nfs_stat_to_errno(status);	res->linkmax = ntohl(*p++);	res->namelen = ntohl(*p++);	/* ignore remaining fields */	return 0;}/* * Decode COMMIT reply */static intnfs3_xdr_commitres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res){	int		status;	status = ntohl(*p++);	p = xdr_decode_wcc_data(p, res->fattr);	if (status != 0)		return -nfs_stat_to_errno(status);	res->verf->verifier[0] = *p++;	res->verf->verifier[1] = *p++;	return 0;}#ifndef MAX# define MAX(a, b)	(((a) > (b))? (a) : (b))#endif#define PROC(proc, argtype, restype)				\    { "nfs3_" #proc,						\      (kxdrproc_t) nfs3_xdr_##argtype,				\      (kxdrproc_t) nfs3_xdr_##restype,				\      MAX(NFS3_##argtype##_sz,NFS3_##restype##_sz) << 2,	\      0							\    }static struct rpc_procinfo	nfs3_procedures[22] = {  PROC(null,		enc_void,	dec_void),  PROC(getattr,		fhandle,	attrstat),  PROC(setattr, 	sattrargs,	wccstat),  PROC(lookup,		diropargs,	lookupres),  PROC(access,		accessargs,	accessres),  PROC(readlink,	readlinkargs,	readlinkres),  PROC(read,		readargs,	readres),  PROC(write,		writeargs,	writeres),  PROC(create,		createargs,	createres),  PROC(mkdir,		mkdirargs,	createres),  PROC(symlink,		symlinkargs,	createres),  PROC(mknod,		mknodargs,	createres),  PROC(remove,		diropargs,	wccstat),  PROC(rmdir,		diropargs,	wccstat),  PROC(rename,		renameargs,	renameres),  PROC(link,		linkargs,	linkres),  PROC(readdir,		readdirargs,	readdirres),  PROC(readdirplus,	readdirargs,	readdirres),  PROC(fsstat,		fhandle,	fsstatres),  PROC(fsinfo,  	fhandle,	fsinfores),  PROC(pathconf,	fhandle,	pathconfres),  PROC(commit,		commitargs,	commitres),};struct rpc_version		nfs_version3 = {	3,	sizeof(nfs3_procedures)/sizeof(nfs3_procedures[0]),	nfs3_procedures};

⌨️ 快捷键说明

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