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

📄 nfs3proc.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * linux/fs/nfsd/nfs3proc.c * * Process version 3 NFS requests. * * Copyright (C) 1996, 1997, 1998 Olaf Kirch <okir@monad.swb.de> */#include <linux/linkage.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/locks.h>#include <linux/fs.h>#include <linux/ext2_fs.h>#include <linux/stat.h>#include <linux/fcntl.h>#include <linux/net.h>#include <linux/in.h>#include <linux/version.h>#include <linux/unistd.h>#include <linux/slab.h>#include <linux/major.h>#include <linux/sunrpc/svc.h>#include <linux/nfsd/nfsd.h>#include <linux/nfsd/cache.h>#include <linux/nfsd/xdr3.h>#include <linux/nfs3.h>#define NFSDDBG_FACILITY		NFSDDBG_PROC#define RETURN_STATUS(st)	{ resp->status = (st); return (st); }static int	nfs3_ftypes[] = {	0,			/* NF3NON */	S_IFREG,		/* NF3REG */	S_IFDIR,		/* NF3DIR */	S_IFBLK,		/* NF3BLK */	S_IFCHR,		/* NF3CHR */	S_IFLNK,		/* NF3LNK */	S_IFSOCK,		/* NF3SOCK */	S_IFIFO,		/* NF3FIFO */};/* * Reserve room in the send buffer */static voidsvcbuf_reserve(struct svc_buf *buf, u32 **ptr, int *len, int nr){	*ptr = buf->buf + nr;	*len = buf->buflen - buf->len - nr;}/* * NULL call. */static intnfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp){	return nfs_ok;}/* * Get a file's attributes */static intnfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,					   struct nfsd3_attrstat *resp){	int	nfserr;	dprintk("nfsd: GETATTR(3)  %s\n",				SVCFH_fmt(&argp->fh));	fh_copy(&resp->fh, &argp->fh);	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);	RETURN_STATUS(nfserr);}/* * Set a file's attributes */static intnfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp,					   struct nfsd3_attrstat  *resp){	int	nfserr;	dprintk("nfsd: SETATTR(3)  %s\n",				SVCFH_fmt(&argp->fh));	fh_copy(&resp->fh, &argp->fh);	nfserr = nfsd_setattr(rqstp, &resp->fh, &argp->attrs,			      argp->check_guard, argp->guardtime);	RETURN_STATUS(nfserr);}/* * Look up a path name component */static intnfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,					  struct nfsd3_diropres  *resp){	int	nfserr;	dprintk("nfsd: LOOKUP(3)   %s %.*s\n",				SVCFH_fmt(&argp->fh),				argp->len,				argp->name);	fh_copy(&resp->dirfh, &argp->fh);	fh_init(&resp->fh, NFS3_FHSIZE);	nfserr = nfsd_lookup(rqstp, &resp->dirfh,				    argp->name,				    argp->len,				    &resp->fh);	RETURN_STATUS(nfserr);}/* * Check file access */static intnfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,					  struct nfsd3_accessres *resp){	int	nfserr;	dprintk("nfsd: ACCESS(3)   %s 0x%x\n",				SVCFH_fmt(&argp->fh),				argp->access);	fh_copy(&resp->fh, &argp->fh);	resp->access = argp->access;	nfserr = nfsd_access(rqstp, &resp->fh, &resp->access);	RETURN_STATUS(nfserr);}/* * Read a symlink. */static intnfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd_fhandle     *argp,					   struct nfsd3_readlinkres *resp){	u32		*path;	int		dummy, nfserr;	dprintk("nfsd: READLINK(3) %s\n", SVCFH_fmt(&argp->fh));	/* Reserve room for status, post_op_attr, and path length */	svcbuf_reserve(&rqstp->rq_resbuf, &path, &dummy,				1 + NFS3_POST_OP_ATTR_WORDS + 1);	/* Read the symlink. */	fh_copy(&resp->fh, &argp->fh);	resp->len = NFS3_MAXPATHLEN;	nfserr = nfsd_readlink(rqstp, &resp->fh, (char *) path, &resp->len);	RETURN_STATUS(nfserr);}/* * Read a portion of a file. */static intnfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,				        struct nfsd3_readres  *resp){	u32 *	buffer;	int	nfserr, avail;	dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",				SVCFH_fmt(&argp->fh),				(unsigned long) argp->count,				(unsigned long) argp->offset);	/* Obtain buffer pointer for payload.	 * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof)	 * + 1 (xdr opaque byte count) = 26	 */	svcbuf_reserve(&rqstp->rq_resbuf, &buffer, &avail,			1 + NFS3_POST_OP_ATTR_WORDS + 3);	resp->count = argp->count;	if ((avail << 2) < resp->count)		resp->count = avail << 2;	fh_copy(&resp->fh, &argp->fh);	nfserr = nfsd_read(rqstp, &resp->fh,				  argp->offset,				  (char *) buffer,				  &resp->count);	if (nfserr == 0) {		struct inode	*inode = resp->fh.fh_dentry->d_inode;		resp->eof = (argp->offset + resp->count) >= inode->i_size;	}	RETURN_STATUS(nfserr);}/* * Write data to a file */static intnfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,					 struct nfsd3_writeres  *resp){	int	nfserr;	dprintk("nfsd: WRITE(3)    %s %d bytes at %ld%s\n",				SVCFH_fmt(&argp->fh),				argp->len,				(unsigned long) argp->offset,				argp->stable? " stable" : "");	fh_copy(&resp->fh, &argp->fh);	resp->committed = argp->stable;	nfserr = nfsd_write(rqstp, &resp->fh,				   argp->offset,				   argp->data,				   argp->len,				   &resp->committed);	resp->count = argp->count;	RETURN_STATUS(nfserr);}/* * With NFSv3, CREATE processing is a lot easier than with NFSv2. * At least in theory; we'll see how it fares in practice when the * first reports about SunOS compatibility problems start to pour in... */static intnfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,					  struct nfsd3_diropres   *resp){	svc_fh		*dirfhp, *newfhp = NULL;	struct iattr	*attr;	u32		nfserr;	dprintk("nfsd: CREATE(3)   %s %.*s\n",				SVCFH_fmt(&argp->fh),				argp->len,				argp->name);	dirfhp = fh_copy(&resp->dirfh, &argp->fh);	newfhp = fh_init(&resp->fh, NFS3_FHSIZE);	attr   = &argp->attrs;	/* Get the directory inode */	nfserr = fh_verify(rqstp, dirfhp, S_IFDIR, MAY_CREATE);	if (nfserr)		RETURN_STATUS(nfserr);	/* Unfudge the mode bits */	attr->ia_mode &= ~S_IFMT;	if (!(attr->ia_valid & ATTR_MODE)) { 		attr->ia_valid |= ATTR_MODE;		attr->ia_mode = S_IFREG;	} else {		attr->ia_mode = (attr->ia_mode & ~S_IFMT) | S_IFREG;	}	/* Now create the file and set attributes */	nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len,				attr, newfhp,				argp->createmode, argp->verf);	RETURN_STATUS(nfserr);}/* * Make directory. This operation is not idempotent. */static intnfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,					 struct nfsd3_diropres   *resp){	int	nfserr;	dprintk("nfsd: MKDIR(3)    %s %.*s\n",				SVCFH_fmt(&argp->fh),				argp->len,				argp->name);	argp->attrs.ia_valid &= ~ATTR_SIZE;	fh_copy(&resp->dirfh, &argp->fh);	fh_init(&resp->fh, NFS3_FHSIZE);	nfserr = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,				    &argp->attrs, S_IFDIR, 0, &resp->fh);	RETURN_STATUS(nfserr);}static intnfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp,					   struct nfsd3_diropres    *resp){	int	nfserr;	dprintk("nfsd: SYMLINK(3)  %s %.*s -> %.*s\n",				SVCFH_fmt(&argp->ffh),				argp->flen, argp->fname,				argp->tlen, argp->tname);	fh_copy(&resp->dirfh, &argp->ffh);	fh_init(&resp->fh, NFS3_FHSIZE);	nfserr = nfsd_symlink(rqstp, &resp->dirfh, argp->fname, argp->flen,						   argp->tname, argp->tlen,						   &resp->fh, &argp->attrs);	RETURN_STATUS(nfserr);}/* * Make socket/fifo/device. */static intnfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp,					 struct nfsd3_diropres  *resp){	int	nfserr, type;	dev_t	rdev = 0;	dprintk("nfsd: MKNOD(3)    %s %.*s\n",				SVCFH_fmt(&argp->fh),				argp->len,				argp->name);	fh_copy(&resp->dirfh, &argp->fh);	fh_init(&resp->fh, NFS3_FHSIZE);	if (argp->ftype == 0 || argp->ftype >= NF3BAD)		RETURN_STATUS(nfserr_inval);	if (argp->ftype == NF3CHR || argp->ftype == NF3BLK) {		if ((argp->ftype == NF3CHR && argp->major >= MAX_CHRDEV)		    || (argp->ftype == NF3BLK && argp->major >= MAX_BLKDEV)		    || argp->minor > 0xFF)			RETURN_STATUS(nfserr_inval);		rdev = ((argp->major) << 8) | (argp->minor);

⌨️ 快捷键说明

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