V4/nsys/ken/iget.c

Compare this file to the similar file:
Show the results in this format:

#include "/sys/nsys/param.h"
#include "/sys/nsys/systm.h"
#include "/sys/nsys/user.h"
#include "/sys/nsys/inode.h"
#include "/sys/nsys/conf.h"
#include "/sys/nsys/buf.h"

iget(dev, ino)
int dev;
int ino;
{
	struct inode *p;
	int *ip, *ip1, *ip2;
	int i;

loop:
	ip = NULL;
	p = &inode[0];
	for(i=0; i<NINODE; i++) {
		if(dev==p->i_dev && ino==p->i_number) {
			if((p->i_flag&ILOCK) != 0) {
				p->i_flag =| IWANT;
				sleep(p, PINOD);
				p->i_flag =& ~IWANT;
				goto loop;
			}
			if((p->i_flag&IMOUNT) != 0)
			for(i=0; i<NMOUNT; i++)
			if(mount[i].m_inodp == p) {
				dev = mount[i].m_dev;
				ino = ROOTINO;
				goto loop;
			}
			p->i_count++;
			p->i_flag =| ILOCK;
			return(p);
		}
		if(ip==NULL && p->i_count==0)
			ip = p;
		p++;
	}
	if((p=ip) == NULL)
		panic("no inodes");
	p->i_dev = dev;
	p->i_number = ino;
	p->i_flag = ILOCK;
	p->i_count++;
	ip = bread(dev,ldiv(0,ino+31,16));
	ip1 = ip->b_addr + 32*lrem(0,ino+31,16);
	ip2 = &p->i_mode;

	/* NOTE
	 * magic number 12 below
	 * is difference between
	 * i_mode and i_addr[8]
	 */

	for(i=0; i<12; i++)
		*ip2++ = *ip1++;
	brelse(ip);
	wakeup(p);
	return(p);
}

iput(p)
struct inode *p;
{

	if(p->i_count == 1) {
		p->i_flag =| ILOCK;
		if(p->i_nlink <= 0) {
			itrunc(p);
			p->i_mode = 0;
			ifree(p->i_dev, p->i_number);
		}
		iupdat(p);
		p->i_flag = 0;
		p->i_number = 0;
		p->i_count = 0;
		wakeup(p);
		return;
	}
	p->i_count--;
	p->i_flag =& ~ILOCK;
	if(p->i_flag&IWANT)
		wakeup(p);
}

iupdat(p)
int *p;
{
	register *ip1, *ip2;
	int *bp, i;

	if((p->i_flag&(IUPD|IACC)) != 0) {
		i = p->i_number+31;
		bp = bread(p->i_dev,ldiv(0,i,16));
		ip1 = bp->b_addr + 32*lrem(0,i,16);
		ip2 = &p->i_mode;

		/*
		 * see above NOTE
		 */

		for(i=0; i<12; i++)
			*ip1++ = *ip2++;
		if(p->i_flag&IACC) {
			*ip1++ = time[0];
			*ip1++ = time[1];
		} else
			ip1 =+ 2;
		if(p->i_flag&IUPD) {
			*ip1++ = time[0];
			*ip1++ = time[1];
		}
		bwrite(bp);
		p->i_flag =& ~(IACC|IUPD);
	}
}

itrunc(ip)
int *ip;
{
	int i, j, a, b, d;
	int *bp, *cp;

	if((ip->i_mode&(IFCHR&IFBLK)) != 0)
		return;
	d = ip->i_dev;
	for(i=0; i<8; i++)
		if(a = ip->i_addr[i]) {
			if((ip->i_mode&ILARG) != 0) {
				bp = bread(d, a);
				cp = bp->b_addr;
				for(j=0; j<256; j++)
					if(b = *cp++)
						free(d, b);
				brelse(bp);
			}
			free(d, a);
			ip->i_addr[i] = 0;
		}
	ip->i_mode =& ~ILARG;
	ip->i_size0 = 0;
	ip->i_size1 = 0;
	ip->i_flag =| IUPD;
}

maknode(mode)
{
	int *ip, i;

	ip = ialloc(u.u_pdir->i_dev);
	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;
	ip->i_size0 = 0;
	ip->i_size1 = 0;
	for(i=0; i<8; i++)
		ip->i_addr[i] = 0;
	wdir(ip);
	return(ip);
}

wdir(ip)
int *ip;
{
	int i;

	u.u_dent.u_ino = ip->i_number;
	for(i=0; i<DIRSIZ; i++)
		u.u_dent.u_name[i] = u.u_dbuf[i];
	u.u_count = DIRSIZ+2;
	u.u_segflg = 1;
	u.u_base = &u.u_dent;
	writei(u.u_pdir);
	iput(u.u_pdir);
}