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

📄 ufs_subr.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lintstatic        char sccsid[] = "@(#)ufs_subr.c 1.1 92/07/30 Copyr 1986 Sun Micro";#endif/* * Copyright (c) 1986 by Sun Microsystems, Inc. */#ifdef KERNEL#include <sys/param.h>#include "boot/systm.h"#include <sys/buf.h>#include <sys/user.h>#include <sys/vfs.h>#include "boot/vnode.h"#include <sys/kernel.h>#include "boot/inode.h"#include <ufs/mount.h>#include <ufs/fs.h>#else#include <sys/param.h>#include <ufs/fs.h>#endif#ifdef	NFS_BOOT#include <mon/sunromvec.h>#endif	 /* NFS_BOOT */#ifdef	 NEVER#ifdef KERNELint	syncprt = 0;/* * Update is the internal name of 'sync'.  It goes through the disk * queues to initiate sandbagged IO; goes through the inodes to write * modified nodes; and it goes through the mount table to initiate * the writing of the modified super blocks. */update(){	register struct inode *ip;	register struct mount *mp;	struct fs *fs;	if (syncprt)		bufstats();	if (updlock)		return;	updlock++;	/*	 * Write back modified superblocks.	 * Consistency check that the superblock	 * of each file system is still in the buffer cache.	 */	for (mp = mounttab; mp != NULL; mp = mp->m_nxt) {		if (mp->m_bufp == NULL || mp->m_dev == NODEV)			continue;		fs = mp->m_bufp->b_un.b_fs;		if (fs->fs_fmod == 0)			continue;		if (fs->fs_ronly != 0) {		/* XXX */			printf("fs = %s\n", fs->fs_fsmnt);			panic("update: rofs mod");		}		fs->fs_fmod = 0;		fs->fs_time = time.tv_sec;		sbupdate(mp);	}	/*	 * Write back each (modified) inode.	 */	for (ip = inode; ip < inodeNINODE; ip++) {		if ((ip->i_flag & ILOCKED) != 0 || (ip->i_flag & IREF) == 0 ||		    (ip->i_flag & (IACC | IUPD | ICHG)) == 0)			continue;		ip->i_flag |= ILOCKED;		VN_HOLD(ITOV(ip));		iupdat(ip, 0);		iput(ip);	}	updlock = 0;	/*	 * Force stale buffer cache information to be flushed,	 * for all devices.	 */	bflush((struct vnode *) 0);}/* * Flush all the blocks associated with an inode. * Note that we make a more stringent check of * writing out any block in the buffer pool that may * overlap the inode. This brings the inode up to * date with recent mods to the cooked device. */syncip(ip)	register struct inode *ip;{	register struct fs *fs;	long lbn, lastlbn;	daddr_t blkno;	fs = ip->i_fs;	lastlbn = howmany(ip->i_size, fs->fs_bsize);	for (lbn = 0; lbn < lastlbn; lbn++) {		blkno = fsbtodb(fs, bmap(ip, lbn, B_READ));		blkflush(ip->i_devvp, blkno, (long)blksize(fs, ip, lbn));	}	imark(ip, ICHG);	iupdat(ip, 1);}#endif KERNELextern	int around[9];extern	int inside[9];extern	u_char *fragtbl[];/* * Update the frsum fields to reflect addition or deletion  * of some frags. */fragacct(fs, fragmap, fraglist, cnt)	struct fs *fs;	int fragmap;	long fraglist[];	int cnt;{	int inblk;	register int field, subfield;	register int siz, pos;	inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;	fragmap <<= 1;	for (siz = 1; siz < fs->fs_frag; siz++) {		if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)			continue;		field = around[siz];		subfield = inside[siz];		for (pos = siz; pos <= fs->fs_frag; pos++) {			if ((fragmap & field) == subfield) {				fraglist[siz] += cnt;				pos += siz;				field <<= siz;				subfield <<= siz;			}			field <<= 1;			subfield <<= 1;		}	}}#ifdef KERNEL/* * Check that a specified block number is in range. */badblock(fs, bn)	register struct fs *fs;	daddr_t bn;{	if ((unsigned)bn >= fs->fs_size) {		printf("bad block %d, ", bn);		fserr(fs, "bad block");		return (1);	}	return (0);}#endif KERNEL/* * block operations * * check if a block is available */isblock(fs, cp, h)	struct fs *fs;	unsigned char *cp;	daddr_t h;{	unsigned char mask;	switch (fs->fs_frag) {	case 8:		return (cp[h] == 0xff);	case 4:		mask = 0x0f << ((h & 0x1) << 2);		return ((cp[h >> 1] & mask) == mask);	case 2:		mask = 0x03 << ((h & 0x3) << 1);		return ((cp[h >> 2] & mask) == mask);	case 1:		mask = 0x01 << (h & 0x7);		return ((cp[h >> 3] & mask) == mask);	default:		panic("isblock");		return (NULL);	}}/* * take a block out of the map */clrblock(fs, cp, h)	struct fs *fs;	u_char *cp;	daddr_t h;{	switch ((fs)->fs_frag) {	case 8:		cp[h] = 0;		return;	case 4:		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));		return;	case 2:		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));		return;	case 1:		cp[h >> 3] &= ~(0x01 << (h & 0x7));		return;	default:		panic("clrblock");	}}/* * put a block into the map */setblock(fs, cp, h)	struct fs *fs;	unsigned char *cp;	daddr_t h;{	switch (fs->fs_frag) {	case 8:		cp[h] = 0xff;		return;	case 4:		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));		return;	case 2:		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));		return;	case 1:		cp[h >> 3] |= (0x01 << (h & 0x7));		return;	default:		panic("setblock");	}}#endif	 /* NEVER */#ifdef KERNELstruct mount *getmp(dev)	dev_t dev;{	register struct mount *mp;	register struct fs *fs;	for (mp = mounttab; mp != NULL; mp = mp->m_nxt) {		if (mp->m_bufp == NULL || mp->m_dev != dev)			continue;		fs = mp->m_bufp->b_un.b_fs;		if (fs->fs_magic != FS_MAGIC) {			printf("dev = 0x%x, fs = %s\n", dev, fs->fs_fsmnt);			panic("getmp: bad magic");		}		return (mp);	}	return (NULL);}/* * Print out statistics on the current allocation of the buffer pool. * Can be enabled to print out on every ``sync'' by setting "syncprt" * above. */bufstats(){	int s, i, j, count;	register struct buf *bp, *dp;	int counts[MAXBSIZE/CLBYTES+1];	static char *bname[BQUEUES] = { "LOCKED", "LRU", "AGE", "EMPTY" };	for (bp = bfreelist, i = 0; bp < &bfreelist[BQUEUES]; bp++, i++) {		count = 0;		for (j = 0; j <= MAXBSIZE/CLBYTES; j++)			counts[j] = 0;		s = spl6();		for (dp = bp->av_forw; dp != bp; dp = dp->av_forw) {			counts[dp->b_bufsize/CLBYTES]++;			count++;		}		(void) splx(s);		printf("%s: total-%d", bname[i], count);		for (j = 0; j <= MAXBSIZE/CLBYTES; j++)			if (counts[j] != 0)				printf(", %d-%d", j * CLBYTES, counts[j]);		printf("\n");	}}/* * Warn that a system table is full. */tablefull(tab)        char *tab;{        printf("%s: table is full\n", tab);}#endif KERNEL

⌨️ 快捷键说明

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