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

📄 nfs2xdr.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Encode SYMLINK arguments */static intnfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args){	p = xdr_encode_fhandle(p, args->fromfh);	p = xdr_encode_array(p, args->fromname, args->fromlen);	p = xdr_encode_array(p, args->topath, args->tolen);	p = xdr_encode_sattr(p, args->sattr);	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);	return 0;}/* * Encode arguments to readdir call */static intnfs_xdr_readdirargs(struct rpc_rqst *req, u32 *p, struct nfs_readdirargs *args){	struct rpc_task	*task = req->rq_task;	struct rpc_auth	*auth = task->tk_auth;	u32		bufsiz = args->bufsiz;	int		buflen, replen;	/*	 * Some servers (e.g. HP OS 9.5) seem to expect the buffer size	 * to be in longwords ... check whether to convert the size.	 */	if (task->tk_client->cl_flags & NFS_CLNTF_BUFSIZE)		bufsiz = bufsiz >> 2;	p = xdr_encode_fhandle(p, args->fh);	*p++ = htonl(args->cookie);	*p++ = htonl(bufsiz); /* see above */	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);	/* set up reply iovec */	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_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're not really decoding anymore, we just leave the buffer untouched * and only check that it is syntactically correct. * The real decoding happens in nfs_decode_entry below, called directly * from nfs_readdir for each entry. */static intnfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs_readdirres *res){	struct iovec		*iov = req->rq_rvec;	int			 hdrlen;	int			 status, nr;	u32			*end, *entry, len;	if ((status = ntohl(*p++)))		return -nfs_stat_to_errno(status);	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);	}	/* Get start and end address of XDR data */	p   = (u32 *) iov[1].iov_base;	end = (u32 *) ((u8 *) p + iov[1].iov_len);	for (nr = 0; *p++; nr++) {		entry = p - 1;		if (p + 2 > end)			goto short_pkt;		p++; /* fileid */		len = ntohl(*p++);		p += XDR_QUADLEN(len) + 1;	/* name plus cookie */		if (len > NFS2_MAXNAMLEN) {			printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)!\n",						len);			return -errno_NFSERR_IO;		}		if (p + 2 > end)			goto short_pkt;	}	return nr; short_pkt:	printk(KERN_NOTICE "NFS: short packet in readdir reply!\n");	entry[0] = entry[1] = 0;	return nr;}u32 *nfs_decode_dirent(u32 *p, struct nfs_entry *entry, int plus){	if (!*p++) {		if (!*p)			return ERR_PTR(-EAGAIN);		entry->eof = 1;		return ERR_PTR(-EBADCOOKIE);	}	entry->ino	  = ntohl(*p++);	entry->len	  = ntohl(*p++);	entry->name	  = (const char *) p;	p		 += XDR_QUADLEN(entry->len);	entry->prev_cookie	  = entry->cookie;	entry->cookie	  = ntohl(*p++);	entry->eof	  = !p[0] && p[1];	return p;}/* * NFS XDR decode functions *//* * Decode void reply */static intnfs_xdr_dec_void(struct rpc_rqst *req, u32 *p, void *dummy){	return 0;}/* * Decode simple status reply */static intnfs_xdr_stat(struct rpc_rqst *req, u32 *p, void *dummy){	int	status;	if ((status = ntohl(*p++)) != 0)		status = -nfs_stat_to_errno(status);	return status;}/* * Decode attrstat reply * GETATTR, SETATTR, WRITE */static intnfs_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 diropres reply * LOOKUP, CREATE, MKDIR */static intnfs_xdr_diropres(struct rpc_rqst *req, u32 *p, struct nfs_diropok *res){	int	status;	if ((status = ntohl(*p++)))		return -nfs_stat_to_errno(status);	p = xdr_decode_fhandle(p, res->fh);	xdr_decode_fattr(p, res->fattr);	return 0;}/* * Encode READLINK args */static intnfs_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_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 + NFS_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 intnfs_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_readlinkres *res){	struct iovec *iov = req->rq_rvec;	u32	*strlen;	char	*string;	int	hdrlen;	int	status;	unsigned int len;	if ((status = ntohl(*p++)))		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 WRITE reply */static intnfs_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res){	res->verf->committed = NFS_FILE_SYNC;	return nfs_xdr_attrstat(req, p, res->fattr);}/* * Decode STATFS reply */static intnfs_xdr_statfsres(struct rpc_rqst *req, u32 *p, struct nfs_fsinfo *res){	int	status;	u32	xfer_size;	if ((status = ntohl(*p++)))		return -nfs_stat_to_errno(status);	/* For NFSv2, we more or less have to guess the preferred	 * read/write/readdir sizes from the single 'transfer size'	 * value.	 */	xfer_size = ntohl(*p++);	/* tsize */	res->rtmax  = 8 * 1024;	res->rtpref = xfer_size;	res->rtmult = xfer_size;	res->wtmax  = 8 * 1024;	res->wtpref = xfer_size;	res->wtmult = xfer_size;	res->dtpref = PAGE_CACHE_SIZE;	res->maxfilesize = 0x7FFFFFFF;	/* just a guess */	res->bsize  = ntohl(*p++);	res->tbytes = ntohl(*p++) * res->bsize;	res->fbytes = ntohl(*p++) * res->bsize;	res->abytes = ntohl(*p++) * res->bsize;	res->tfiles = 0;	res->ffiles = 0;	res->afiles = 0;	res->namelen = 0;	return 0;}/* * We need to translate between nfs status return values and * the local errno values which may not be the same. */static struct {	int stat;	int errno;} nfs_errtbl[] = {	{ NFS_OK,		0		},	{ NFSERR_PERM,		EPERM		},	{ NFSERR_NOENT,		ENOENT		},	{ NFSERR_IO,		errno_NFSERR_IO	},	{ NFSERR_NXIO,		ENXIO		},/*	{ NFSERR_EAGAIN,	EAGAIN		}, */	{ NFSERR_ACCES,		EACCES		},	{ NFSERR_EXIST,		EEXIST		},	{ NFSERR_XDEV,		EXDEV		},	{ NFSERR_NODEV,		ENODEV		},	{ NFSERR_NOTDIR,	ENOTDIR		},	{ NFSERR_ISDIR,		EISDIR		},	{ NFSERR_INVAL,		EINVAL		},	{ NFSERR_FBIG,		EFBIG		},	{ NFSERR_NOSPC,		ENOSPC		},	{ NFSERR_ROFS,		EROFS		},	{ NFSERR_MLINK,		EMLINK		},	{ NFSERR_NAMETOOLONG,	ENAMETOOLONG	},	{ NFSERR_NOTEMPTY,	ENOTEMPTY	},	{ NFSERR_DQUOT,		EDQUOT		},	{ NFSERR_STALE,		ESTALE		},	{ NFSERR_REMOTE,	EREMOTE		},#ifdef EWFLUSH	{ NFSERR_WFLUSH,	EWFLUSH		},#endif	{ NFSERR_BADHANDLE,	EBADHANDLE	},	{ NFSERR_NOT_SYNC,	ENOTSYNC	},	{ NFSERR_BAD_COOKIE,	EBADCOOKIE	},	{ NFSERR_NOTSUPP,	ENOTSUPP	},	{ NFSERR_TOOSMALL,	ETOOSMALL	},	{ NFSERR_SERVERFAULT,	ESERVERFAULT	},	{ NFSERR_BADTYPE,	EBADTYPE	},	{ NFSERR_JUKEBOX,	EJUKEBOX	},	{ -1,			EIO		}};/* * Convert an NFS error code to a local one. * This one is used jointly by NFSv2 and NFSv3. */intnfs_stat_to_errno(int stat){	int i;	for (i = 0; nfs_errtbl[i].stat != -1; i++) {		if (nfs_errtbl[i].stat == stat)			return nfs_errtbl[i].errno;	}	printk(KERN_ERR "nfs_stat_to_errno: bad nfs status return value: %d\n", stat);	return nfs_errtbl[i].errno;}#ifndef MAX# define MAX(a, b)	(((a) > (b))? (a) : (b))#endif#define PROC(proc, argtype, restype)	\    { "nfs_" #proc,					\      (kxdrproc_t) nfs_xdr_##argtype,			\      (kxdrproc_t) nfs_xdr_##restype,			\      MAX(NFS_##argtype##_sz,NFS_##restype##_sz) << 2,	\      0							\    }static struct rpc_procinfo	nfs_procedures[18] = {    PROC(null,		enc_void,	dec_void),    PROC(getattr,	fhandle,	attrstat),    PROC(setattr,	sattrargs,	attrstat),    PROC(root,		enc_void,	dec_void),    PROC(lookup,	diropargs,	diropres),    PROC(readlink,	readlinkargs,	readlinkres),    PROC(read,		readargs,	readres),    PROC(writecache,	enc_void,	dec_void),    PROC(write,		writeargs,	writeres),    PROC(create,	createargs,	diropres),    PROC(remove,	diropargs,	stat),    PROC(rename,	renameargs,	stat),    PROC(link,		linkargs,	stat),    PROC(symlink,	symlinkargs,	stat),    PROC(mkdir,		createargs,	diropres),    PROC(rmdir,		diropargs,	stat),    PROC(readdir,	readdirargs,	readdirres),    PROC(statfs,	fhandle,	statfsres),};struct rpc_version		nfs_version2 = {	2,	sizeof(nfs_procedures)/sizeof(nfs_procedures[0]),	nfs_procedures};

⌨️ 快捷键说明

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