Nsys/sys/nsys/ken/iget.c
#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);
}