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

📄 vnodeops_gfs.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)vnodeops_gfs.c	4.6	(ULTRIX)	4/11/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1986,87 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * *   Modification history: * * 11 Apr 91 -- chet *	Fix truncate past end of file case for remote mapped files. * * 03 March 91 -- larry *	Fix vop_create().  Will not create a non-zero length file. * * 27 Feb 91 -- chet *	Fix remote utimes(2). * * 18 Feb 91 -- prs *	Added SAVE_DIRP to the source namei op in vop_rename(). Since *	the local file system rename routine assumes the source name *	string has not been altered, we must ensure namei restores it. *	namei will trash ni_dirp when symbolic links are followed without *	SAVE_DIRP. * * 27 Aug 90 -- chet *	Redo vop_link since target gp now arrives unlocked. * * 07 Mar 90 -- prs *	Fixed vop_rename() to unlock parent directories of target *	and source node before calling local rename routine. * * 09 Oct 89 -- prs *	Added checks to vop_rmdir() and vop_rename() to prevent  *	operations on mount points. * * 21 Sep 89 -- prs *	Modified vop_rename() to unlock sdp before call to GNAMEI *	to prevent a panic condition. * * 24 Apr 89 -- chet *	change vop_create() to not call GNAMEI with LOCKPARENT; *	LOCKPARENT required write permission in directory to overwrite *	a file with write permission. * * 06 Apr 89 -- prs *	Added SMP quota locks. * * 11 Oct 88 -- prs *	Added the restriction to vop_rmdir() that insures the gnode *	being operated on is a directory. * * 28 Sep 88 -- chet *	Add casts to unsigned for -1 checks in unsigned vattr fields * * 22 Aug 88 -- prs *	Changed vop_setattr() and vop_create() to only allow root to *	set the sticky bit on a regular file, and allow the owner of *	a directory to set the sticky bit on a directory they own. * * 04 Aug 88 -- chet *	Add checks for LINK_MAX and linked directories in vop_link(). * * 28 Jul 88 -- prs *	Decremented the link count of the source gnode in vop_link(), * 	when an error condition is detected. * * 07 Mar 88 -- prs *	Removed parity bit check in vop_create() for I18N. *  * 14 Jan 88 -- chet *	Changed permission checks in vop_setattr() for access and mod times *	to owner * * 13 Nov 87 -- chet *	Removed vulnerability to protocol violation in vop_create(). * * 15 Oct 87 -- chet *	Removed panics in vop_remove and vop_rdwr * * 14-Jul-87 -- cb *	mknod interface changed. * * 31-Mar-87 -- logcher *	Merged in Chet's changes, see comments from 1.16.1.1 *  * 02-Mar-87 -- logcher *	Merged in diskless changes, added VFIFO to gftovt_tab and *	GFPORT to vttogf_tab, changed GMAKNODE line in vop_create *	to allow mknod  *//* * This file is an attempt to emulate the VFS operations done by the * NFS code with GFS operations. By convention, all gnodes are passed * in unlocked and remain unlocked, and gnodes returned are unlocked. */#include "../h/types.h"#include "../h/param.h"#include "../h/systm.h"#include "../ufs/fs.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/mount.h"#include "../h/kernel.h"#include "../h/uio.h"#include "../h/buf.h"#include "../h/limits.h"#include "../net/netinet/in.h"#include "../net/rpc/types.h"#include "../nfs/nfs_clnt.h"#include "../nfs/vfs.h"#include "../nfs/nfs.h"#include "../nfs/vnode.h"#include "../ufs/ufs_inode.h"#ifdef QUOTA#include "../h/quota.h"#endif/* * Convert between vnode types and gnode formats */enum vtype gftovt_tab[] = {	VNON, VCHR, VDIR, VBLK, VREG, VLNK, VSOCK, VFIFO, VBAD};int vttogf_tab[] = {	0, GFREG, GFDIR, GFBLK, GFCHR, GFLNK, GFSOCK, GFPORT, GFMT};intvop_getattr(gp, vap, cred)	struct gnode *gp;	register struct vattr *vap;	struct ucred *cred;{	int ret;		ret = GGETVAL(gp);	vap->va_type = IFTOVT(gp->g_mode);	vap->va_mode = gp->g_mode;	vap->va_uid = gp->g_uid;	vap->va_gid = gp->g_gid;	vap->va_fsid = gp->g_dev;	vap->va_nodeid = gp->g_number;	vap->va_nlink = gp->g_nlink;	vap->va_size = gp->g_size;	vap->va_atime = gp->g_atime;	vap->va_mtime = gp->g_mtime;	vap->va_ctime = gp->g_ctime;	vap->va_rdev = gp->g_rdev;	vap->va_blocks = gp->g_blocks;	switch(gp->g_mode & GFMT) {	case GFBLK:		vap->va_blocksize = BLKDEV_IOSIZE;				break;	case GFCHR:		vap->va_blocksize = MAXBSIZE;		break;	default:		vap->va_blocksize = gp->g_mp->m_fs_data->fd_bsize;		break;	}	return (0);}intvop_setattr(gp, vap, cred)	register struct gnode *gp;	register struct vattr *vap;	struct ucred *cred;{	int error = 0;	int changed = 0;	struct timeval atime;	struct timeval mtime;		atime = *(timepick);	mtime = *(timepick);		/*	 * cannot set these attributes	 */	if ((vap->va_nlink != -1) || (vap->va_blocksize != -1) ||	    (vap->va_rdev != -1) || (vap->va_blocks != -1) ||	    (vap->va_fsid != -1) || (vap->va_nodeid != -1)) {		return (EINVAL);	}	/* sanity check time values */	if (vap->va_atime.tv_sec != -1) {		if (vap->va_atime.tv_sec < 0)			return (EINVAL);		if (vap->va_atime.tv_usec < 0 ||		    vap->va_atime.tv_usec >= 1000000)			vap->va_atime.tv_usec = 0;	}	if (vap->va_mtime.tv_sec != -1) {		if (vap->va_mtime.tv_sec < 0)			return (EINVAL);		if (vap->va_mtime.tv_usec < 0 ||		    vap->va_mtime.tv_usec >= 1000000)			vap->va_mtime.tv_usec = 0;	}	/*	 * Change file access modes. Must be owner or su.	 */	if (vap->va_mode != (u_short) -1) {		error = OWNER(gp, cred);		if (error)			goto out;		gp->g_mode &= GFMT;		gp->g_mode |= vap->va_mode & ~GFMT;		/*		 * Only root can set the sticky bit on a regular file.		 * However, the owner of a directory can set the sticky		 * bit, for their directory.		 */		if ((gp->g_mode & GFMT) != GFDIR) {			if (u.u_uid)				gp->g_mode &= ~GSVTX;		}		if (u.u_uid) {			if (!groupmember(gp->g_gid))				gp->g_mode &= ~GSGID;		}		gp->g_flag |= GCHG;		++changed;		/* Remember to xrele text if su ever allowed over net. */	}	/*	 * Change file ownership (must be su).	 */	if ( ((vap->va_uid != -1) && (vap->va_uid != gp->g_uid)) ||	     ((vap->va_gid != -1) && (vap->va_gid != gp->g_gid)) )	{		if (!suser()) {			error = u.u_error;			goto out;		}		error = chown2(gp, vap->va_uid, vap->va_gid);		if (error)			goto out;		++changed;	}	/*	 * Truncate file. Must have write permission and not be a directory.	 */	if (vap->va_size != (u_long) -1) {		if ((gp->g_mode & GFMT) == GFDIR) {			error = EISDIR;			goto out;		}		if (access(gp, GWRITE)) {			error = u.u_error;			goto out;		}		/*		 * Do the right thing with truncate size.		 * Setting the size beyond current size is a mapped		 * file'ism first seen with SysVR4 SunOS at Cthon '91.		 */		if (vap->va_size > gp->g_size) {			struct iovec iov;			struct uio uio;			char c = '\0';			iov.iov_base = &c;			iov.iov_len = 1;			uio.uio_iov = &iov;			uio.uio_iovcnt = 1;			uio.uio_segflg = UIO_SYSSPACE;			uio.uio_offset = vap->va_size;			uio.uio_resid = 1;			error = vop_rdwr(gp, &uio, UIO_WRITE,					 IO_SYNC, u.u_cred);		} else {			(void)GTRUNC(gp, vap->va_size, cred);			++changed;		}	}	/*	 * Change file access or modified times.	 */	if (vap->va_atime.tv_sec != -1) {		error = OWNER(gp, cred);		if (error) {			goto out;		}		atime.tv_sec = vap->va_atime.tv_sec;		atime.tv_usec = vap->va_atime.tv_usec;		gp->g_flag |= GACC|GCHG;		++changed;	}	if (vap->va_mtime.tv_sec != -1) {		error = OWNER(gp, cred);		if (error) {			goto out;		}		mtime.tv_sec = vap->va_mtime.tv_sec;		mtime.tv_usec = vap->va_mtime.tv_usec;		gp->g_flag |= GUPD|GCHG;		++changed;	}out:	if (changed)		(void) GUPDATE(gp, &atime, &mtime, 1, cred);	return (error);}intvop_lookup(dgp, name, gpp, cred)	struct gnode *dgp;	char *name;	struct gnode **gpp;	struct ucred *cred;{	struct nameidata *ndp = &u.u_nd;	ndp->ni_dirp = name;	ndp->ni_nameiop = LOOKUP | NOMOUNT;	u.u_cdir = dgp;	gfs_unlock(dgp);	if(*gpp = GNAMEI(ndp))		gfs_unlock(*gpp);	gfs_lock(dgp);	return (u.u_error);}intvop_readlink(gp, uiop, cred)	struct gnode *gp;	struct uio *uiop;	struct ucred *cred;{	(void) GREADLINK(gp, uiop);	return (u.u_error);}intvop_access(gp, mode, cred)	struct gnode *gp;	int mode;	struct ucred *cred;{	u.u_error = 0;	access(gp, mode);	return (u.u_error);}intvop_rdwr(gp, uiop, rw, syncflg, cred)	struct gnode *gp;	struct uio *uiop;	int rw;	int syncflg;	struct ucred *cred;{	int error;	if ((gp->g_mode & GFMT) == GFREG) {		error = GRWGP(gp, uiop, rw, syncflg, cred);	}	else {		error = u.u_error = EINVAL;	}	return (error);}intvop_create(dgp, name, vap, exclusive, garbage, gpp, cred)	struct gnode *dgp;	register char *name;	struct vattr *vap;	int exclusive;	int garbage;	struct gnode **gpp;	struct ucred *cred;{	register struct nameidata *ndp = &u.u_nd;	register struct gnode *gp;	register char *cp;		/*	 * Disallow filenames with slashes, since the GFS	 * pathname parsing scheme assigns a special meaning to them.	 * This is a problem: Sun's implementation allows clients to	 * use whatever they want for pathname delimiters, whereas ours	 * presupposes that "/" is a delimiter and cannot allow it	 * to be used in a filename.  This may someday become an issue	 * in a heterogeneous environment with Ultrix NFS servers.	 */		cp = name;	while (*cp)		/*		 * Removed parity bit check for I18N.		 */		if (*cp == '/') {			u.u_error = EINVAL;			return(u.u_error);		}		else			cp++;		ndp->ni_dirp = name;	ndp->ni_nameiop = CREATE | NOMOUNT;	u.u_cdir = dgp;	gfs_unlock(dgp);	*gpp = GNAMEI(ndp);	if (*gpp == NULL) {		if (u.u_error)			return (u.u_error);		/*		 * Only root can create a regular file with the sticky bit		 * set.		 */		if (u.u_uid)			vap->va_mode &= ~GSVTX;		if ((vap->va_size != (u_long) 0) &&		    (vap->va_size != (u_long) -1)) {			u.u_error = EINVAL;		/* ??? */			*gpp = ndp->ni_pdir;			goto bad;		}		/*		 * allow mknod over the wire 		 */		if ((*gpp = GMAKNODE(vap->va_mode, vap->va_rdev, ndp))		    == (struct gnode *) GNOFUNC) {			u.u_error = EOPNOTSUPP;		        goto bad2;		}		if (*gpp == NULL)			goto bad2;	} else {		if (exclusive) {			u.u_error = EEXIST;

⌨️ 快捷键说明

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