# #include "../defines.h" #include "../param.h" #include "../file.h" #ifdef AUSAML #include "../lnode.h" #endif AUSAML #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" */ #ifdef MAPPED_BUFFERS /* * ka5 must be preserved */ #endif MAPPED_BUFFERS iget(dev, ino) { register struct inode *p; #ifndef MAPPED_BUFFERS register *ip2; int *ip1; #else MAPPED_BUFFERS register unsigned ka5sav; #endif MAPPED_BUFFERS 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); } #ifndef LRU_INODE if(ip==NULL && p->i_count==0) ip = p; #endif LRU_INODE #ifdef LRU_INODE if(p->i_count==0) if( (ip==NULL) || (ip->i_lrt > p->i_lrt) ) ip = p; #endif LRU_INODE } 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; #ifdef LOCKING p->i_lockf = p->i_lockc = 0; #endif ip = bread(dev, ldiv(ino+31,16)); /* * Check I/O errors */ if (ip->b_flags&B_ERROR) { brelse(ip); iput(p); return(NULL); } #ifndef MAPPED_BUFFERS ip1 = ip->b_addr + 32*lrem(ino+31, 16); ip2 = &p->i_mode; while(ip2 < &p->i_addr[8]) *ip2++ = *ip1++; #else MAPPED_BUFFERS ka5sav = ka5; bswtch( ip ); bcopy( b.buff + 32*lrem(ino+31, 16) , &p->i_mode , 12 ); ka5 = ka5sav; #endif MAPPED_BUFFERS 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. #ifdef MAPPED_BUFFERS * * KA5 to be preserved * #endif MAPPED_BUFFERS */ iput(p) struct inode *p; { register *rp; #ifdef MAPPED_BUFFERS register ka5sav = ka5; #endif MAPPED_BUFFERS rp = p; if(rp->i_count == 1) { rp->i_flag =| ILOCK; if(rp->i_nlink <= 0) { itrunc(rp); rp->i_mode = 0; rp->i_flag =| IUPD; /* fix025 */ ifree(rp->i_dev, rp->i_number); } iupdat(rp, time); prele(rp); rp->i_flag = 0; #ifndef LRU_INODE rp->i_number = 0; #endif LRU_INODE #ifdef LRU_INODE rp->i_lrt = time.loint; #endif LRU_INODE } else if (rp->i_nlink <= 0) /* fix044 */ { rp->i_mode =& ~077; /* chmod 0 (watch out for pipes) */ #ifdef AUSAM16 rp->i_uidl = 0; rp->i_uidh = 0; /* chown root */ #else rp->i_uid = 0; #endif } /* end of fix044 */ rp->i_count--; prele(rp); #ifdef MAPPED_BUFFERS ka5 = ka5sav; #endif MAPPED_BUFFERS } /* * 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. #ifdef MAPPED_BUFFERS * * KA5 must be preserved * #endif MAPPED_BUFFERS */ iupdat(p, tm) int *p; long tm; /* fix000 */ { register *ip1, *ip2, *rp; int *bp, i; #ifdef MAPPED_BUFFERS int ka5sav = ka5; #endif MAPPED_BUFFERS rp = p; if((rp->i_flag&(IUPD|IACC)) != 0) { if(getfs(rp->i_dev)->s_ronly) #ifdef MAPPED_BUFFERS goto ret; #else MAPPED_BUFFERS return; #endif MAPPED_BUFFERS i = rp->i_number+31; bp = bread(rp->i_dev, ldiv(i,16)); #ifdef MAPPED_BUFFERS bswtch( bp ); ip1 = b.buff + 32*lrem(i, 16); #else MAPPED_BUFFERS ip1 = bp->b_addr + 32*lrem(i, 16); #endif MAPPED_BUFFERS ip2 = &rp->i_mode; while(ip2 < &rp->i_addr[8]) *ip1++ = *ip2++; if(rp->i_flag&IACC) { *ip1++ = time.hiint; /* fix000 */ *ip1++ = time.loint; /* fix000 */ } else ip1 =+ 2; if(rp->i_flag&IUPD) { *ip1++ = tm.hiint; /* fix000 */ *ip1++ = tm.loint; /* fix000 */ } rp->i_flag =& ~(IUPD | IACC); /* fix025 */ bdwrite(bp); /* fix025 */ } #ifdef MAPPED_BUFFERS ret: ka5 = ka5sav; #endif MAPPED_BUFFERS } /* * 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); #ifdef MAPPED_BUFFERS bswtch( bp ); /* fix025 */ for(cp = b.buff+510; cp >= b.buff; cp--) #else MAPPED_BUFFERS /* fix025 */ for(cp = bp->b_addr+510; cp >= bp->b_addr; cp--) #endif MAPPED_BUFFERS if(*cp) { if(ip == &rp->i_addr[7]) { #ifdef MAPPED_BUFFERS int ka5sav; #endif MAPPED_BUFFERS dp = bread(rp->i_dev, *cp); #ifdef MAPPED_BUFFERS ka5sav = ka5; bswtch( dp ); /* fix025 */ for(ep = b.buff+510; ep >= b.buff; ep--) #else MAPPED_BUFFERS /* fix025 */ for(ep = dp->b_addr+510; ep >= dp->b_addr; ep--) #endif MAPPED_BUFFERS if(*ep) free(rp->i_dev, *ep); #ifdef MAPPED_BUFFERS ka5 = ka5sav; #endif MAPPED_BUFFERS 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) { iput( u.u_pdir ); /* fix025 */ return(NULL); } ip->i_flag =| IACC|IUPD; ip->i_mode = mode|IALLOC; ip->i_nlink = 1; #ifndef AUSAM16 ip->i_uid = u.u_uid; ip->i_gid = u.u_gid; #endif AUSAM16 #ifdef AUSAM16 ip->i_uidl = u.u_uid.lobyte; ip->i_uidh = u.u_uid.hibyte; #endif AUSAM16 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 = SEG_KER; u.u_base = &u.u_dent; writei(u.u_pdir); iput(u.u_pdir); }