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

📄 nfsproc.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * nfsproc2.c	Process version 2 NFS requests. * linux/fs/nfsd/nfs2proc.c *  * Process version 2 NFS requests. * * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de> */#include <linux/linkage.h>#include <linux/time.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/stat.h>#include <linux/fcntl.h>#include <linux/net.h>#include <linux/in.h>#include <linux/namei.h>#include <linux/unistd.h>#include <linux/slab.h>#include <linux/sunrpc/clnt.h>#include <linux/sunrpc/svc.h>#include <linux/nfsd/nfsd.h>#include <linux/nfsd/cache.h>#include <linux/nfsd/xdr.h>typedef struct svc_rqst	svc_rqst;typedef struct svc_buf	svc_buf;#define NFSDDBG_FACILITY		NFSDDBG_PROCstatic __be32nfsd_proc_null(struct svc_rqst *rqstp, void *argp, void *resp){	return nfs_ok;}static __be32nfsd_return_attrs(__be32 err, struct nfsd_attrstat *resp){	if (err) return err;	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,				    resp->fh.fh_dentry,				    &resp->stat));}static __be32nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp){	if (err) return err;	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,				    resp->fh.fh_dentry,				    &resp->stat));}/* * Get a file's attributes * N.B. After this call resp->fh needs an fh_put */static __be32nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,					  struct nfsd_attrstat *resp){	__be32 nfserr;	dprintk("nfsd: GETATTR  %s\n", SVCFH_fmt(&argp->fh));	fh_copy(&resp->fh, &argp->fh);	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);	return nfsd_return_attrs(nfserr, resp);}/* * Set a file's attributes * N.B. After this call resp->fh needs an fh_put */static __be32nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,					  struct nfsd_attrstat  *resp){	__be32 nfserr;	dprintk("nfsd: SETATTR  %s, valid=%x, size=%ld\n",		SVCFH_fmt(&argp->fh),		argp->attrs.ia_valid, (long) argp->attrs.ia_size);	fh_copy(&resp->fh, &argp->fh);	nfserr = nfsd_setattr(rqstp, &resp->fh, &argp->attrs,0, (time_t)0);	return nfsd_return_attrs(nfserr, resp);}/* * Look up a path name component * Note: the dentry in the resp->fh may be negative if the file * doesn't exist yet. * N.B. After this call resp->fh needs an fh_put */static __be32nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,					 struct nfsd_diropres  *resp){	__be32	nfserr;	dprintk("nfsd: LOOKUP   %s %.*s\n",		SVCFH_fmt(&argp->fh), argp->len, argp->name);	fh_init(&resp->fh, NFS_FHSIZE);	nfserr = nfsd_lookup(rqstp, &argp->fh, argp->name, argp->len,				 &resp->fh);	fh_put(&argp->fh);	return nfsd_return_dirop(nfserr, resp);}/* * Read a symlink. */static __be32nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_readlinkargs *argp,					   struct nfsd_readlinkres *resp){	__be32	nfserr;	dprintk("nfsd: READLINK %s\n", SVCFH_fmt(&argp->fh));	/* Read the symlink. */	resp->len = NFS_MAXPATHLEN;	nfserr = nfsd_readlink(rqstp, &argp->fh, argp->buffer, &resp->len);	fh_put(&argp->fh);	return nfserr;}/* * Read a portion of a file. * N.B. After this call resp->fh needs an fh_put */static __be32nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,				       struct nfsd_readres  *resp){	__be32	nfserr;	dprintk("nfsd: READ    %s %d bytes at %d\n",		SVCFH_fmt(&argp->fh),		argp->count, argp->offset);	/* Obtain buffer pointer for payload. 19 is 1 word for	 * status, 17 words for fattr, and 1 word for the byte count.	 */	if (NFSSVC_MAXBLKSIZE_V2 < argp->count) {		char buf[RPC_MAX_ADDRBUFLEN];		printk(KERN_NOTICE			"oversized read request from %s (%d bytes)\n",				svc_print_addr(rqstp, buf, sizeof(buf)),				argp->count);		argp->count = NFSSVC_MAXBLKSIZE_V2;	}	svc_reserve_auth(rqstp, (19<<2) + argp->count + 4);	resp->count = argp->count;	nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,				  argp->offset,			   	  rqstp->rq_vec, argp->vlen,				  &resp->count);	if (nfserr) return nfserr;	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,				    resp->fh.fh_dentry,				    &resp->stat));}/* * Write data to a file * N.B. After this call resp->fh needs an fh_put */static __be32nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp,					struct nfsd_attrstat  *resp){	__be32	nfserr;	int	stable = 1;	dprintk("nfsd: WRITE    %s %d bytes at %d\n",		SVCFH_fmt(&argp->fh),		argp->len, argp->offset);	nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,				   argp->offset,				   rqstp->rq_vec, argp->vlen,				   argp->len,				   &stable);	return nfsd_return_attrs(nfserr, resp);}/* * CREATE processing is complicated. The keyword here is `overloaded.' * The parent directory is kept locked between the check for existence * and the actual create() call in compliance with VFS protocols. * N.B. After this call _both_ argp->fh and resp->fh need an fh_put */static __be32nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,					 struct nfsd_diropres   *resp){	svc_fh		*dirfhp = &argp->fh;	svc_fh		*newfhp = &resp->fh;	struct iattr	*attr = &argp->attrs;	struct inode	*inode;	struct dentry	*dchild;	int		type, mode;	__be32		nfserr;	dev_t		rdev = 0, wanted = new_decode_dev(attr->ia_size);	dprintk("nfsd: CREATE   %s %.*s\n",		SVCFH_fmt(dirfhp), argp->len, argp->name);	/* First verify the parent file handle */	nfserr = fh_verify(rqstp, dirfhp, S_IFDIR, MAY_EXEC);	if (nfserr)		goto done; /* must fh_put dirfhp even on error */	/* Check for MAY_WRITE in nfsd_create if necessary */	nfserr = nfserr_acces;	if (!argp->len)		goto done;	nfserr = nfserr_exist;	if (isdotent(argp->name, argp->len))		goto done;	fh_lock_nested(dirfhp, I_MUTEX_PARENT);	dchild = lookup_one_len(argp->name, dirfhp->fh_dentry, argp->len);	if (IS_ERR(dchild)) {		nfserr = nfserrno(PTR_ERR(dchild));		goto out_unlock;	}	fh_init(newfhp, NFS_FHSIZE);	nfserr = fh_compose(newfhp, dirfhp->fh_export, dchild, dirfhp);	if (!nfserr && !dchild->d_inode)		nfserr = nfserr_noent;	dput(dchild);	if (nfserr) {		if (nfserr != nfserr_noent)			goto out_unlock;		/*		 * If the new file handle wasn't verified, we can't tell		 * whether the file exists or not. Time to bail ...		 */		nfserr = nfserr_acces;		if (!newfhp->fh_dentry) {			printk(KERN_WARNING 				"nfsd_proc_create: file handle not verified\n");			goto out_unlock;		}	}	inode = newfhp->fh_dentry->d_inode;	/* Unfudge the mode bits */	if (attr->ia_valid & ATTR_MODE) {		type = attr->ia_mode & S_IFMT;		mode = attr->ia_mode & ~S_IFMT;		if (!type) {			/* no type, so if target exists, assume same as that,			 * else assume a file */			if (inode) {				type = inode->i_mode & S_IFMT;				switch(type) {				case S_IFCHR:				case S_IFBLK:					/* reserve rdev for later checking */					rdev = inode->i_rdev;					attr->ia_valid |= ATTR_SIZE;					/* FALLTHROUGH */				case S_IFIFO:					/* this is probably a permission check..					 * at least IRIX implements perm checking on					 *   echo thing > device-special-file-or-pipe					 * by doing a CREATE with type==0					 */					nfserr = nfsd_permission(rqstp,								 newfhp->fh_export,								 newfhp->fh_dentry,								 MAY_WRITE|MAY_LOCAL_ACCESS);					if (nfserr && nfserr != nfserr_rofs)						goto out_unlock;				}			} else				type = S_IFREG;		}	} else if (inode) {		type = inode->i_mode & S_IFMT;		mode = inode->i_mode & ~S_IFMT;	} else {		type = S_IFREG;		mode = 0;	/* ??? */	}	attr->ia_valid |= ATTR_MODE;	attr->ia_mode = mode;	/* Special treatment for non-regular files according to the	 * gospel of sun micro	 */	if (type != S_IFREG) {		int	is_borc = 0;		if (type != S_IFBLK && type != S_IFCHR) {			rdev = 0;		} else if (type == S_IFCHR && !(attr->ia_valid & ATTR_SIZE)) {			/* If you think you've seen the worst, grok this. */			type = S_IFIFO;		} else {			/* Okay, char or block special */			is_borc = 1;			if (!rdev)				rdev = wanted;		}

⌨️ 快捷键说明

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