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

📄 alloc.c

📁 UNIX v6源代码 这几乎是最经典的unix版本 unix操作系统设计和莱昂氏unix源代码分析都是用的该版
💻 C
字号:
#/* */#include "../param.h"#include "../systm.h"#include "../filsys.h"#include "../conf.h"#include "../buf.h"#include "../inode.h"#include "../user.h"/* * iinit is called once (from main) * very early in initialization. * It reads the root's super block * and initializes the current date * from the last modified date. * * panic: iinit -- cannot read the super * block. Usually because of an IO error. */iinit(){	register *cp, *bp;	(*bdevsw[rootdev.d_major].d_open)(rootdev, 1);	bp = bread(rootdev, 1);	cp = getblk(NODEV);	if(u.u_error)		panic("iinit");	bcopy(bp->b_addr, cp->b_addr, 256);	brelse(bp);	mount[0].m_bufp = cp;	mount[0].m_dev = rootdev;	cp = cp->b_addr;	cp->s_flock = 0;	cp->s_ilock = 0;	cp->s_ronly = 0;	time[0] = cp->s_time[0];	time[1] = cp->s_time[1];}/* * alloc will obtain the next available * free disk block from the free list of * the specified device. * The super block has up to 100 remembered * free blocks; the last of these is read to * obtain 100 more . . . * * no space on dev x/y -- when * the free list is exhausted. */alloc(dev){	int bno;	register *bp, *ip, *fp;	fp = getfs(dev);	while(fp->s_flock)		sleep(&fp->s_flock, PINOD);	do {		if(fp->s_nfree <= 0)			goto nospace;		bno = fp->s_free[--fp->s_nfree];		if(bno == 0)			goto nospace;	} while (badblock(fp, bno, dev));	if(fp->s_nfree <= 0) {		fp->s_flock++;		bp = bread(dev, bno);		ip = bp->b_addr;		fp->s_nfree = *ip++;		bcopy(ip, fp->s_free, 100);		brelse(bp);		fp->s_flock = 0;		wakeup(&fp->s_flock);	}	bp = getblk(dev, bno);	clrbuf(bp);	fp->s_fmod = 1;	return(bp);nospace:	fp->s_nfree = 0;	prdev("no space", dev);	u.u_error = ENOSPC;	return(NULL);}/* * place the specified disk block * back on the free list of the * specified device. */free(dev, bno){	register *fp, *bp, *ip;	fp = getfs(dev);	fp->s_fmod = 1;	while(fp->s_flock)		sleep(&fp->s_flock, PINOD);	if (badblock(fp, bno, dev))		return;	if(fp->s_nfree <= 0) {		fp->s_nfree = 1;		fp->s_free[0] = 0;	}	if(fp->s_nfree >= 100) {		fp->s_flock++;		bp = getblk(dev, bno);		ip = bp->b_addr;		*ip++ = fp->s_nfree;		bcopy(fp->s_free, ip, 100);		fp->s_nfree = 0;		bwrite(bp);		fp->s_flock = 0;		wakeup(&fp->s_flock);	}	fp->s_free[fp->s_nfree++] = bno;	fp->s_fmod = 1;}/* * Check that a block number is in the * range between the I list and the size * of the device. * This is used mainly to check that a * garbage file system has not been mounted. * * bad block on dev x/y -- not in range */badblock(afp, abn, dev){	register struct filsys *fp;	register char *bn;	fp = afp;	bn = abn;	if (bn < fp->s_isize+2 || bn >= fp->s_fsize) {		prdev("bad block", dev);		return(1);	}	return(0);}/* * Allocate an unused I node * on the specified device. * Used with file creation. * The algorithm keeps up to * 100 spare I nodes in the * super block. When this runs out, * a linear search through the * I list is instituted to pick * up 100 more. */ialloc(dev){	register *fp, *bp, *ip;	int i, j, k, ino;	fp = getfs(dev);	while(fp->s_ilock)		sleep(&fp->s_ilock, PINOD);loop:	if(fp->s_ninode > 0) {		ino = fp->s_inode[--fp->s_ninode];		ip = iget(dev, ino);		if (ip==NULL)			return(NULL);		if(ip->i_mode == 0) {			for(bp = &ip->i_mode; bp < &ip->i_addr[8];)				*bp++ = 0;			fp->s_fmod = 1;			return(ip);		}		/*		 * Inode was allocated after all.		 * Look some more.		 */		iput(ip);		goto loop;	}	fp->s_ilock++;	ino = 0;	for(i=0; i<fp->s_isize; i++) {		bp = bread(dev, i+2);		ip = bp->b_addr;		for(j=0; j<256; j=+16) {			ino++;			if(ip[j] != 0)				continue;			for(k=0; k<NINODE; k++)			if(dev==inode[k].i_dev && ino==inode[k].i_number)				goto cont;			fp->s_inode[fp->s_ninode++] = ino;			if(fp->s_ninode >= 100)				break;		cont:;		}		brelse(bp);		if(fp->s_ninode >= 100)			break;	}	fp->s_ilock = 0;	wakeup(&fp->s_ilock);	if (fp->s_ninode > 0)		goto loop;	prdev("Out of inodes", dev);	u.u_error = ENOSPC;	return(NULL);}/* * Free the specified I node * on the specified device. * The algorithm stores up * to 100 I nodes in the super * block and throws away any more. */ifree(dev, ino){	register *fp;	fp = getfs(dev);	if(fp->s_ilock)		return;	if(fp->s_ninode >= 100)		return;	fp->s_inode[fp->s_ninode++] = ino;	fp->s_fmod = 1;}/* * getfs maps a device number into * a pointer to the incore super * block. * The algorithm is a linear * search through the mount table. * A consistency check of the * in core free-block and i-node * counts. * * bad count on dev x/y -- the count *	check failed. At this point, all *	the counts are zeroed which will *	almost certainly lead to "no space" *	diagnostic * panic: no fs -- the device is not mounted. *	this "cannot happen" */getfs(dev){	register struct mount *p;	register char *n1, *n2;	for(p = &mount[0]; p < &mount[NMOUNT]; p++)	if(p->m_bufp != NULL && p->m_dev == dev) {		p = p->m_bufp->b_addr;		n1 = p->s_nfree;		n2 = p->s_ninode;		if(n1 > 100 || n2 > 100) {			prdev("bad count", dev);			p->s_nfree = 0;			p->s_ninode = 0;		}		return(p);	}	panic("no fs");}/* * update is the internal name of * 'sync'. It goes through the disk * queues to initiate sandbagged IO; * goes through the I nodes to write * modified nodes; and it goes through * the mount table to initiate modified * super blocks. */update(){	register struct inode *ip;	register struct mount *mp;	register *bp;	if(updlock)		return;	updlock++;	for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++)		if(mp->m_bufp != NULL) {			ip = mp->m_bufp->b_addr;			if(ip->s_fmod==0 || ip->s_ilock!=0 ||			   ip->s_flock!=0 || ip->s_ronly!=0)				continue;			bp = getblk(mp->m_dev, 1);			ip->s_fmod = 0;			ip->s_time[0] = time[0];			ip->s_time[1] = time[1];			bcopy(ip, bp->b_addr, 256);			bwrite(bp);		}	for(ip = &inode[0]; ip < &inode[NINODE]; ip++)		if((ip->i_flag&ILOCK) == 0) {			ip->i_flag =| ILOCK;			iupdat(ip, time);			prele(ip);		}	updlock = 0;	bflush(NODEV);}

⌨️ 快捷键说明

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