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

📄 iget.c

📁 UNIX v6源代码 这几乎是最经典的unix版本 unix操作系统设计和莱昂氏unix源代码分析都是用的该版
💻 C
字号:
##include "../param.h"#include "../systm.h"#include "../user.h"#include "../inode.h"#include "../filsys.h"#include "../conf.h"#include "../buf.h"/* * Look up an inode by device,inumber. * If it is in core (in the inode structure), * honor the locking protocol. * If it is not in core, read it in from the * specified device. * If the inode is mounted on, perform * the indicated indirection. * In all cases, a pointer to a locked * inode structure is returned. * * printf warning: no inodes -- if the inode *	structure is full * panic: no imt -- if the mounted file *	system is not in the mount table. *	"cannot happen" */iget(dev, ino){	register struct inode *p;	register *ip2;	int *ip1;	register struct mount *ip;loop:	ip = NULL;	for(p = &inode[0]; p < &inode[NINODE]; p++) {		if(dev==p->i_dev && ino==p->i_number) {			if((p->i_flag&ILOCK) != 0) {				p->i_flag =| IWANT;				sleep(p, PINOD);				goto loop;			}			if((p->i_flag&IMOUNT) != 0) {				for(ip = &mount[0]; ip < &mount[NMOUNT]; ip++)				if(ip->m_inodp == p) {					dev = ip->m_dev;					ino = ROOTINO;					goto loop;				}				panic("no imt");			}			p->i_count++;			p->i_flag =| ILOCK;			return(p);		}		if(ip==NULL && p->i_count==0)			ip = p;	}	if((p=ip) == NULL) {		printf("Inode table overflow\n");		u.u_error = ENFILE;		return(NULL);	}	p->i_dev = dev;	p->i_number = ino;	p->i_flag = ILOCK;	p->i_count++;	p->i_lastr = -1;	ip = bread(dev, ldiv(ino+31,16));	/*	 * Check I/O errors	 */	if (ip->b_flags&B_ERROR) {		brelse(ip);		iput(p);		return(NULL);	}	ip1 = ip->b_addr + 32*lrem(ino+31, 16);	ip2 = &p->i_mode;	while(ip2 < &p->i_addr[8])		*ip2++ = *ip1++;	brelse(ip);	return(p);}/* * Decrement reference count of * an inode structure. * On the last reference, * write the inode out and if necessary, * truncate and deallocate the file. */iput(p)struct inode *p;{	register *rp;	rp = p;	if(rp->i_count == 1) {		rp->i_flag =| ILOCK;		if(rp->i_nlink <= 0) {			itrunc(rp);			rp->i_mode = 0;			ifree(rp->i_dev, rp->i_number);		}		iupdat(rp, time);		prele(rp);		rp->i_flag = 0;		rp->i_number = 0;	}	rp->i_count--;	prele(rp);}/* * Check accessed and update flags on * an inode structure. * If either is on, update the inode * with the corresponding dates * set to the argument tm. */iupdat(p, tm)int *p;int *tm;{	register *ip1, *ip2, *rp;	int *bp, i;	rp = p;	if((rp->i_flag&(IUPD|IACC)) != 0) {		if(getfs(rp->i_dev)->s_ronly)			return;		i = rp->i_number+31;		bp = bread(rp->i_dev, ldiv(i,16));		ip1 = bp->b_addr + 32*lrem(i, 16);		ip2 = &rp->i_mode;		while(ip2 < &rp->i_addr[8])			*ip1++ = *ip2++;		if(rp->i_flag&IACC) {			*ip1++ = time[0];			*ip1++ = time[1];		} else			ip1 =+ 2;		if(rp->i_flag&IUPD) {			*ip1++ = *tm++;			*ip1++ = *tm;		}		bwrite(bp);	}}/* * Free all the disk blocks associated * with the specified inode structure. * The blocks of the file are removed * in reverse order. This FILO * algorithm will tend to maintain * a contiguous free list much longer * than FIFO. */itrunc(ip)int *ip;{	register *rp, *bp, *cp;	int *dp, *ep;	rp = ip;	if((rp->i_mode&(IFCHR&IFBLK)) != 0)		return;	for(ip = &rp->i_addr[7]; ip >= &rp->i_addr[0]; ip--)	if(*ip) {		if((rp->i_mode&ILARG) != 0) {			bp = bread(rp->i_dev, *ip);			for(cp = bp->b_addr+512; cp >= bp->b_addr; cp--)			if(*cp) {				if(ip == &rp->i_addr[7]) {					dp = bread(rp->i_dev, *cp);					for(ep = dp->b_addr+512; ep >= dp->b_addr; ep--)					if(*ep)						free(rp->i_dev, *ep);					brelse(dp);				}				free(rp->i_dev, *cp);			}			brelse(bp);		}		free(rp->i_dev, *ip);		*ip = 0;	}	rp->i_mode =& ~ILARG;	rp->i_size0 = 0;	rp->i_size1 = 0;	rp->i_flag =| IUPD;}/* * Make a new file. */maknode(mode){	register *ip;	ip = ialloc(u.u_pdir->i_dev);	if (ip==NULL)		return(NULL);	ip->i_flag =| IACC|IUPD;	ip->i_mode = mode|IALLOC;	ip->i_nlink = 1;	ip->i_uid = u.u_uid;	ip->i_gid = u.u_gid;	wdir(ip);	return(ip);}/* * Write a directory entry with * parameters left as side effects * to a call to namei. */wdir(ip)int *ip;{	register char *cp1, *cp2;	u.u_dent.u_ino = ip->i_number;	cp1 = &u.u_dent.u_name[0];	for(cp2 = &u.u_dbuf[0]; cp2 < &u.u_dbuf[DIRSIZ];)		*cp1++ = *cp2++;	u.u_count = DIRSIZ+2;	u.u_segflg = 1;	u.u_base = &u.u_dent;	writei(u.u_pdir);	iput(u.u_pdir);}

⌨️ 快捷键说明

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