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

📄 ufs_gnode.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)ufs_gnode.c	4.6	(ULTRIX)	4/25/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 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: /sys/sys/ufs_gnode.c * * 10 Apr 91 -- prs *	Fixed ufs_gtrunc() to allocate a block if truncating into a hole. * * 27 Feb 91 -- chet *	Fix filesystem timestamping. * * 22-Jan-91 -- prs *      Added fast symbolic link support. * *  9 Mar 90 -- chet *	Fix inode generation number incrementation. * * 25 Jul 89 -- chet *	Changes for syncronous filesystems and remove old debugging code * * 06 Apr 89 -- prs *	Added SMP quota locking. * * 28 Jul 88 -- prs *	SMP - system call work. * * 10 Feb 88 -- prs *	Modified to support new fifo code. * * 08 Feb 88 -- prs *	Removed call to dqrele in ufs_gget. The call is now done *	in getegnode. * * 14 Jan 88 -- chet *	Added gennum++ in ufs_grele when freeing the inode for reuse * * 28 Sep 87 -- prs *	Added a call to ufs_gunlock in the B_ERROR case of ufs_gget. * * 25 Aug 87 -- prs *	Removed a gput call in ufs_gget in the B_ERROR case, that *	would cause the system to panic if condition happened twice. * * 14 Jul 87 -- cb *	Code Cleanup - removed some lingering device special code. * * 08 May 87 -- logcher *	Added else for rdev from new rdev sync described in 01-Apr *	problem. * * 01 Apr 87 -- logcher *	Added fix for 0, 0 problem in ufs_gget() * * 02 Mar 87 -- logcher *	Merged in diskless changes, added support for new ufs_ops *	and specfs * * 29 Jan 87 -- chet *	add new arg to bdwrite() calls. * * 03 Nov 86 -- bglover for koehler *	change bread call indirtrunc rtn (final parameter NULL) * * 11 Sep 86 -- koehler *	gfs changes -- check locking and do synchronous fs writes * * 11 Nov 85 -- depp *	Removed all conditional compiles for System V IPC. * * 15 Mar 85 -- funding *	Added named pipe support (re. System V named pipes) * * 16 Oct 84 -- jrs *	Fix hash, quota release, add igrab and nami cache support * * 17 Jul 84 -- jmcg *	Inserted code to track lockers and unlockers of inodes for *	debugging.  Conditionally compiled by defining RECINODELOCKS. *	Changed a blind lock to an GLOCK (based on suspicions of a *	bug from the net). * * 17 Jul 84 --jmcg *	Began modification history with sources from ULTRIX-32, Rel. V1.0. *	Derived from 4.2BSD, labeled: *		ufs_inode.c	6.1	83/07/29 * * --------------------------------------------------------------------- */#include "../h/param.h"#include "../h/systm.h"#include "../h/mount.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/gnode_common.h"#include "../ufs/ufs_inode.h"#include "../h/gnode.h"#include "../ufs/fs.h"#include "../h/conf.h"#include "../h/buf.h"#ifdef QUOTA#include "../h/quota.h"#endif#include "../h/kernel.h"#include "../h/fs_types.h"#include "../h/cmap.h"#define OSF_FASTLINK 0x0001extern struct gnode_ops *ufs_gnode_ops;intufs_ginit(gp, iflag, ptr)	struct gnode *gp;	int iflag;	caddr_t ptr;{	struct mount *mp = gp->g_mp;	struct fs *fs;	struct buf *bp;	struct ufs_inode *dp;		int type;			gp->g_ops = ufs_gnode_ops;	if (iflag == RECLAIM_GNODE)		panic("ufs reclaim trying too hard");	fs = mp->m_bufp->b_un.b_fs;	bp = bread(mp->m_dev, fsbtodb(fs, itod(fs, gp->g_number)),		(int)fs->fs_bsize, (struct gnode *) NULL);			/*	 * Check I/O errors	 */	if ((bp->b_flags&B_ERROR) != 0) {		brelse(bp);		return(0);	}	dp = bp->b_un.b_dino;	dp += itoo(fs, gp->g_number);	G_TO_I(gp)->di_ic = dp->di_ic;	gp->g_blocks = G_TO_I(gp)->di_blocks;	gp->g_gennum = G_TO_I(gp)->di_gennum;	/*	 * check for specvp 	 */	type = gp->g_mode & GFMT;	if ((type == GFCHR) || (type == GFBLK) || (type == GFPORT)) {		gp->g_rdev = G_TO_I(gp)->di_rdev;		specvp(gp);	} else		gp->g_rdev = NODEV;	brelse(bp);	return(1);}/* * Make a locked gnode inactive.  Another process may create a reference * to this gnode while we're operating on it, but it won't be able to * lock it until we're done.  By then we will have marked it so the * other process will know to initialize it again.	 */ufs_inactive(gp)	register struct gnode *gp;{	register int mode;	gassert(gp);	if (gp->g_nlink <= 0) {		mode = gp->g_mode & GFMT;		if ((mode == GFBLK) || (mode == GFCHR))			gp->g_rdev = G_TO_I(gp)->di_rdev = 0;		gp->g_nlink = 0;						gp->g_mode = 0;		G_TO_I(gp)->di_flags = 0; /* For OSF_FASTLINK */		G_TO_I(gp)->di_gennum = ++(gp->g_gennum);		/*		 * gtrunc does the ufs_gupdat()		 */		ufs_gtrunc(gp, (u_long)0, (struct ucred *) 0);		ufs_gfree(gp, gp->g_number, mode);#ifdef QUOTA		(void) chkiq(gp->g_dev, gp, gp->g_uid, 0);		dquot_lock(gp->g_dquot);		dqrele(gp->g_dquot);		dquot_unlock(gp->g_dquot);		gp->g_dquot = NODQUOT;#endif	}	ufs_gupdat(gp, timepick, timepick, 0, (struct ucred *) 0);}#define	SINGLE	0	/* index of single indirect block */#define	DOUBLE	1	/* index of double indirect block */#define	TRIPLE	2	/* index of triple indirect block *//* * Truncate the gnode gp to at most * length size.  Free affected disk * blocks -- the blocks of the file * are removed in reverse order. * * NB: triple indirect blocks are untested. */ufs_gtrunc(ogp, length, cred)	register struct gnode *ogp;	u_long length;	struct ucred *cred;{	register daddr_t lastblock;	daddr_t bn, lbn, lastiblock[NIADDR];	register struct fs *fs;	register struct ufs_inode *ufs_ip;	struct buf *bp;	int offset, osize, size, count, level, s;	int updat_flag = 0;	long nblocks, blocksreleased = 0;	register int i;	struct gnode tip;	long indirtrunc();	extern struct cmap *mfind();	/*	 * Disable the trunc up case for now. We have to worry about	 * special files before this feature can be enabled.	 */		if (length >= ogp->g_size) {		ogp->g_flag |= GCHG|GUPD;                ufs_gupdat(ogp, timepick, timepick, 0, (struct ucred *) 0);		return(0);	}	/*	 * Fast symbolic links have no storage.  Can truncate in place.	 */	if ((G_TO_I(ogp)->di_flags & OSF_FASTLINK) &&	    (ogp->g_size > length)) {		bzero(&(G_TO_I(ogp)->di_db[length]), ogp->g_size - length);		ogp->g_size = length;		ogp->g_flag |= GCHG|GUPD; 		ufs_gupdat(ogp, timepick, timepick, 0, (struct ucred *) 0);		return;	}	fs = FS(ogp);	offset = blkoff(fs, length);	lbn = lblkno(fs, length - 1);	if (length > ogp->g_size) {		/*		 * Trunc up case.  ufs_bmap will insure that the right blocks		 * are allocated.  This includes extending the old frag to a		 * full block (if needed) in addition to doing any work		 * needed for allocating the last block.		 */		if (offset == 0)			bn = ufs_bmap(ogp, lbn, B_WRITE, (int)fs->fs_bsize,				&updat_flag);		else			bn = ufs_bmap(ogp, lbn, B_WRITE, offset, &updat_flag); 		if (u.u_error == 0 || bn >= (daddr_t)0) {			ogp->g_size = length;			ogp->g_flag |= GCHG;		} 		if (updat_flag != 0)			ufs_gupdat(ogp, timepick, timepick, 1,				   (struct ucred *) 0);		else			ufs_gupdat(ogp, timepick, timepick, 0,				   (struct ucred *) 0);		return (u.u_error);	}	/*	 * Calculate index into gnode's block list of	 * last direct and indirect blocks (if any)	 * which we want to keep.  Lastblock is -1 when	 * the file is truncated to 0.	 */	lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1;	lastiblock[SINGLE] = lastblock - NDADDR;	lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs);	lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs);	nblocks = btodb(fs->fs_bsize);	/*	 * Update the size of the file. If the file is not being	 * truncated to a block boundry, the contents of the	 * partial block following the end of the file must be	 * zero'ed in case it ever become accessable again because	 * of subsequent file growth.	 */	osize = ogp->g_size;	if (offset == 0) {		ogp->g_size = length;	} else {		bn = ufs_bmap(ogp, lbn, B_WRITE, offset, 0);		if (u.u_error || (long)bn < 0)			return(u.u_error);		ogp->g_size = length;		size = blksize(fs, ogp, lbn);		count = howmany(size, DEV_BSIZE);		s = splimp();

⌨️ 快捷键说明

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