struct dinode * ginode(ino_t inumber) { diskaddr_t iblk; diskaddr_t dblk; int ioff; static diskaddr_t curr_dblk; static char buf[MIN_PHYS_READ]; struct dinode *ibuf; if (inumber < UFSROOTINO || (int)inumber > imax) { (void) fprintf(stderr, "bad inode number %ld to ginode\n", inumber); exit(32); } iblk = itod(&sblock, (int)inumber); dblk = fsbtodb(&sblock, iblk); ioff = itoo(&sblock, (int)inumber); if (dblk != curr_dblk) { bread(dblk, &buf[0], sizeof (buf)); curr_dblk = dblk; inode_reads++; } ibuf = (struct dinode *)&buf[0]; ibuf += ioff; return (ibuf); }
Dinode *iget(unsigned int inode) { unsigned int bnum; unsigned int inum; bnum = itod(inode); inum = itoo(inode); readBlock(bnum, (unsigned char *) inodeBlock); return &inodeBlock[inum]; }
static int openi(int n, struct iob *io) { struct dinode *dp; int cc; #if ICACHE struct icommon *ip; if (icache == 0) { icache = cacheInit(ICACHE_SIZE, sizeof(struct icommon)); } #endif ICACHE io->i_offset = 0; io->i_bn = fsbtodb(io->i_fs, itod(io->i_fs, n)) + io->i_boff; io->i_cc = io->i_fs->fs_bsize; io->i_ma = io->i_buf; #if ICACHE if (cacheFind(icache, n, 0, (char **)&ip) == 1) { io->i_ino.i_ic = *ip; cc = 0; } else { #endif ICACHE cc = devread(io); dp = (struct dinode *)io->i_buf; #if BIG_ENDIAN_FS byte_swap_inode_in(&dp[itoo(io->i_fs, n)].di_ic, &io->i_ino.i_ic); #else io->i_ino.i_ic = dp[itoo(io->i_fs, n)].di_ic; #endif BIG_ENDIAN_FS #if ICACHE *ip = io->i_ino.i_ic; } #endif ICACHE io->i_ino.i_number = n; return (cc); }
int kputoct(WORD w) { char buff[7]; itoo(w, buff); return kputstr(buff,6); }
/* write the memory-inode out to the inode-block */ void iput(struct inode *ip, int *aibc, s4_daddr *ib) { struct s4_dinode *dp; s4_daddr d; int i,j,k; s4_daddr ib2[NIDIR]; /* a double indirect block */ filsys->s_tinode--; d = itod(ip->i_number); if(d >= filsys->s_isize) { if(error == 0) printf("ilist too small\n"); error = 1; return; } /* get the existing disk inode block to modify */ rdfs(d, buf, s4b_ino ); dp = (struct s4_dinode *)buf; /* skip to the right entry */ dp += itoo(ip->i_number); /* convert memory to disk format in buffer */ dp->di_mode = ip->i_ftype | ip->i_mode; dp->di_nlink = ip->i_nlink; dp->di_uid = ip->i_uid; dp->di_gid = ip->i_gid; dp->di_size = ip->i_size; dp->di_atime = utime; dp->di_mtime = utime; dp->di_ctime = utime; switch(ip->i_ftype) { case S_IFDIR: case S_IFREG: /* handle direct pointers */ for(i=0; i<*aibc && i<LADDR; i++) { ip->i_faddr[i] = ib[i]; ib[i] = 0; } /* handle single indirect block */ if(i < *aibc) { for(j=0; i<*aibc && j<NIDIR; j++, i++) ib[j] = ib[i]; for(; j<NIDIR; j++) ib[j] = 0; ip->i_faddr[LADDR] = alloc(); wtfs(ip->i_faddr[LADDR], (char *)ib, s4b_idx); } /* handle double indirect block */ if(i < *aibc) { for(k=0; k<NIDIR && i<*aibc; k++) { for(j=0; i<*aibc && j<NIDIR; j++, i++) ib[j] = ib[i]; for(; j<NIDIR; j++) ib[j] = 0; ib2[k] = alloc(); wtfs(ib2[k], (char *)ib, s4b_idx); } for(; k<NIDIR; k++) ib2[k] = 0; ip->i_faddr[LADDR+1] = alloc(); wtfs(ip->i_faddr[LADDR+1], (char *)ib2, s4b_idx ); } /* triple indirect block? Nope. */ if(i < *aibc) { printf("triple indirect blocks not handled\n"); } break; default: printf("bogus ftype %o\n", ip->i_ftype); exit(1); } /* convert the address list to correct disk format */ if( doswap ) s4ltol3r(dp->di_addr, ip->i_faddr, S4_NADDR); else s4ltol3(dp->di_addr, ip->i_faddr, S4_NADDR); wtfs(d, buf, s4b_ino); }