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

📄 gfs_gnodeops.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)gfs_gnodeops.c	4.5	(ULTRIX)	2/28/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1986,87,88,89 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 * * 28 Feb 91 -- prs *	Added support for a configurable number of open *	file descriptors. * * 27 Feb 91 -- chet *	Fix filesystem timestamping * * 21 Jan 91 -- prs *	Added routine divorce_dev() to disassociate gnode from file *	table entry. The gnode pointer is no longer zeroed, it will *	simply stay around until the file table entry goes away, but *	any I/O requests with the file table entry will result in an *	error return. Once divorce_dev runs, the physical device will *	not be called with any open file descriptors. vhangup() and *	gno_close() call divirce_dev(). * * 06 Mar 90 -- scott *	allow negative uio_offset for AUD_NO * *  9 Feb 90 -- prs * 	Fixed a bug in gno_lock() where a branch to `again' didn't *	unlock the gp. * * 12 Jan 90 -- prs *	Changed gno_close() to not check pipes or fifos for file *	table references before calling sfs close routine. * * 14 Nov 89 -- prs *	Removed setting u_error to zero from gno_close(). * * 09 nov 89 -- fran *	Add logic to forceclose to break connection to controlling *	terminal. * * 25 Jul 89 -- chet *	Use new bflush() interface in gno_close() * * 14 Jun 89 -- prs *	Enhanced vhangup() logic to interoperate with closef(). * * 09 Feb 89 -- prs *	Initialized the stack variable `type' in rwgp(). This fixes the *	problem with the routine failing to check if a write would exceed *	the current rlimit for the user. * * 04 Jan 89 -- prs *	Removed the DTYPE_PORT check in gno_close(). Skipping named pipes *	allows the code to only check special devices for multiple file  *	table references for the same device. This fixes a bug where the  *	fifo close routine would only be called on the last reference to  *	the fifo, instead of every call propagating to the sfs close. * * 28 Sep 88 -- chet *      Add cacheinvalall in unlikely event that nextgnodeid wraps. * * 9  Sep 88 -- condylis *	Added SMP changes to gno_lock and gno_unlock * * 19 Jul 88 -- prs *	Cleared g_fifo field in getegnode() routine, to fix a problem *	with fifo gnode reclaiming a non fifo gnode over nfs. * * 11 Jul 88 -- prs *	Modified gno_ioctl to pass the flags filed of a file pointer *	 to the fifo ioctl routine. * * 8  Jul 88 -- condylis *	All gnode types except regular file and directory will now call *	rwgp from gno_rw without the gnode lock held. *	Test added to end of rwgp to insure that gnode lock is held *	while setting GACC bit in gnode flag. * * 19 May 88 -- cb *	Changed GFS interface - SMP safe gnode manipulation. * * 15 Feb 88 -- Tim Burke *	Added field to uio structure called uio_flag. This field will be used  *	pass the file descriptor modes down into the device driver on reads *	and writes to distinguish POSIX nonblocking I/O/ * * 10 Feb 88 -- prs *	Modified to handle the new fifo code. * * 10 Feb 88 -- map *	Don't send SIGXFSZ if in System V mode. * * 08 Feb 88 -- prs *	Changed getegnode to process g_dquot field in gnode. *	Now, gnode returned has this field nulled out, as routine *	name suggests. * * 12 Jan 88 -- Fred Glover *	Add gno_lockrelease routine for Sys-V lock cleanup upon file *	close or process termination * * 28 Dec 87 -- Tim Burke *  	Moved u.u_ttyp to u.u_procp->p_ttyp. * * 23 Mar 87 -- prs *	Fixed gno_close to decrement reference count in gnode *	before returning from special cases. * * 03 Mar 87 -- chase *	refresh gnode attributes before an append mode write * * 03 Mar 87 -- prs *	Changed gno_close to verify block device was not mounted before *	flushing and invalidating all its buffers. * * 29 Jan 87 -- chet *	moved gput() after GCLOSE in gno_close(). * * 19 Sep 86 -- lp *	fixed bug in ioctl code when enabling n-buff. * 11 Sep 86 -- koehler *	fixed close routine * ***********************************************************************/#include "../h/param.h"#include "../h/systm.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/gnode.h"#include "../h/proc.h"#include "../h/conf.h"#include "../h/buf.h"#include "../h/mount.h"#include "../h/file.h"#include "../h/uio.h"#include "../h/ioctl.h"#include "../h/tty.h"#include "../h/cmap.h"#include "../h/stat.h"#include "../h/kernel.h"#include "../h/exec.h"#include "../h/cpudata.h"#ifdef QUOTA#include "../h/quota.h"#endifint	gno_rw(), gno_ioctl(), gno_select(), gno_close();struct 	fileops gnodeops =	{ gno_rw, gno_ioctl, gno_select, gno_close };int 	divorce_rw(), divorce_ioctl(), divorce_select(), divorce_close();struct	fileops divorceops =	{ divorce_rw, divorce_ioctl, divorce_select, divorce_close };gno_rw(fp, rw, uio)	register struct file *fp;	register enum uio_rw rw;	register struct uio *uio;{	register struct gnode *gp = (struct gnode *)fp->f_data;	register int error;		if ((gp->g_mode&GFMT) == GFREG) {		gfs_lock(gp);		if (fp->f_flag&FAPPEND && rw == UIO_WRITE) {			(void)GGETVAL(gp);			uio->uio_offset = fp->f_offset = gp->g_size;		}		/*		 * If synchronous write flag was passed in the file		 * pointer from the open or fcntl system calls,		 * then do a synchronous write.		 */		if (fp->f_flag & O_FSYNC)			error = rwgp(gp, uio, rw, IO_SYNC, fp->f_cred);		else			error = rwgp(gp, uio, rw, IO_ASYNC, fp->f_cred);		gfs_unlock(gp);				} else {		uio->uio_flag = fp->f_flag;		if ((fp->f_flag & FNBLOCK) || (fp->f_flag & FNDELAY))			error = rwgp(gp, uio, rw, IO_ASYNC|FNDELAY, fp->f_cred);		else			error = rwgp(gp, uio, rw, IO_ASYNC, fp->f_cred);	}	return (error);}rdwri(rw, gp, base, len, offset, segflg, aresid)	register struct gnode *gp;	register caddr_t base;	int len, offset, segflg;	register int *aresid;	enum uio_rw rw;{	struct uio _auio;	register struct uio *auio = &_auio;	struct iovec _aiov;	register struct iovec *aiov = &_aiov;	register int error;	auio->uio_iov = aiov;	auio->uio_iovcnt = 1;	aiov->iov_base = base;	aiov->iov_len = len;	auio->uio_resid = len;	auio->uio_offset = offset;	auio->uio_segflg = segflg;	error = rwgp(gp, auio, rw, IO_ASYNC, u.u_cred);	if (aresid)		*aresid = auio->uio_resid;	else		if (auio->uio_resid)			error = EIO;	return (error);}rwgp(gp, uio, rw, ioflag, cred)	register struct gnode *gp;	register struct uio *uio;	register enum uio_rw rw;	int ioflag;	struct ucred *cred;{	dev_t dev = (dev_t)gp->g_rdev;	register int type = (gp->g_mode & GFMT);	extern int mem_no;	register int ret;		if (rw != UIO_READ && rw != UIO_WRITE)		panic("rwgp");	if (rw == UIO_READ && uio->uio_resid == 0)		return (0);	if (uio->uio_offset < 0 &&	    (type != GFCHR || (mem_no != major(dev) && major(dev) != AUD_NO)))		return (EINVAL);			if (rw == UIO_WRITE && type == GFREG && uio->uio_offset +	uio->uio_resid > u.u_rlimit[RLIMIT_FSIZE].rlim_cur) {		if (u.u_procp->p_progenv == A_BSD) /* BSD baggage */			psignal(u.u_procp, SIGXFSZ); 		return (EFBIG);	}		ret = GRWGP(gp, uio, rw, ioflag, cred);	if (!ret && rw == UIO_READ) {		if (ISLOCAL(gp->g_mp)) {			if (smp_owner(&gp->g_lk))				gp->g_flag |= GACC;			else {				gfs_lock(gp);				gp->g_flag |= GACC;				gfs_unlock(gp);			}		}	}	return(ret);}gno_ioctl(fp, com, data, cred)	register struct file *fp;	register int com;	register caddr_t data;	struct ucred *cred;{ 	register struct gnode *gp = ((struct gnode *)fp->f_data);	register int fmt = gp->g_mode & GFMT;	dev_t dev;	register int flag;		switch (fmt) {		case GFREG:		case GFDIR:			if (com == FIONREAD) 				flag = fp->f_offset;			break;		case GFPIPE:		case GFPORT:			flag = fp->f_flag;			break;		case GFCHR:			flag = fp->f_flag;			dev = gp->g_rdev;		       /*			* cdevsw[].d_strat implies this device can			*  do multi-buffered operations. Otherwise		 	*  just fall into device ioctl.			*/			if (cdevsw[major(dev)].d_strat) {				if (com == FIONBUF) {					int *acount = (int *)data;					if (*acount < 0)						return(ENXIO);				   	if (*acount > 0) {						fp->f_flag |= FNBUF;						gp->g_flag |= ASYNC;						startasync(dev, acount,						fp->f_flag);				   	} else if (fp->f_flag&FNBUF) {						if (!asyncclose(dev, fp->f_flag))							gp->g_flag &= ~ASYNC;						fp->f_flag &= ~FNBUF;				   	}			 	  	return(0);				}				if (com == FIONBDONE)					return(aiodone(dev, *(int *)data,					fp->f_flag));				if (com == FIONBIO || com == FIOASYNC)						return(0); 			} else if (com == FIONBUF)				return(ENXIO);	}	if ((flag = GFNCTL(gp, com, data, flag, fp->f_cred)) == GNOFUNC)		flag = EOPNOTSUPP;	return(flag);}gno_select(fp, which)	register struct file *fp;	register int which;{	register struct gnode *gp = (struct gnode *)fp->f_data;	return (GSELECT(gp, which, fp->f_cred));}#ifdef notdefgno_clone(){	return (EOPNOTSUPP);}#endifgno_stat(gp, sb)	register struct gnode *gp;	register struct stat *sb;{	return (GSTAT(gp, sb));}gno_close(fp)	register struct file *fp;{	register struct file *ffp;	register struct gnode *gp = (struct gnode *)fp->f_data;	register int flag;	dev_t dev;	register int mode;		register struct gnode *tgp;	register struct mount *mp;		flag = fp->f_flag;	if (flag & (FSHLOCK|FEXLOCK))		gno_unlock(fp, FSHLOCK|FEXLOCK);	fp->f_ops = &divorceops; /* So we wont be looked at ! */	dev = (dev_t)gp->g_rdev;	mode = gp->g_mode & GFMT;	if (mode == GFCHR || mode == GFBLK) {		/*		 * Check for references to the device. If the device is		 * referenced by another process, simply remove our		 * reference to the gnode. However, if we are the last		 * reference to the device, call spec_close() which will		 * call the drivers close routine, shutting down the device.		 */		for (ffp = file; ffp < fileNFILE; ffp++) {			if (ffp->f_count == 0)				continue;			if (ffp->f_type != DTYPE_INODE)		/* XXX */				continue;			if (ffp->f_ops == &divorceops)				continue;			if ((tgp = (struct gnode *)ffp->f_data) &&			    tgp->g_rdev == dev && (tgp->g_mode&GFMT) == mode) {				/*				 * Decrement ref count in gnode				 */				grele(gp);

⌨️ 快捷键说明

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