X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/5d5124a141271556d98fac9d719b0d1e01585958..5485e062213aa576f431ef766f639e248716dfe8:/usr/src/sys/ufs/ffs/ffs_inode.c?ds=inline diff --git a/usr/src/sys/ufs/ffs/ffs_inode.c b/usr/src/sys/ufs/ffs/ffs_inode.c index b17c214f59..0592361f9e 100644 --- a/usr/src/sys/ufs/ffs/ffs_inode.c +++ b/usr/src/sys/ufs/ffs/ffs_inode.c @@ -1,4 +1,4 @@ -/* ffs_inode.c 3.1 %H% */ +/* ffs_inode.c 4.9 82/02/27 */ #include "../h/param.h" #include "../h/systm.h" @@ -24,11 +24,12 @@ short ifreel; ihinit() { register int i; + register struct inode *ip = inode; ifreel = 0; - for (i = 0; i < NINODE - 1; i++) - inode[i].i_hlink = i+1; - inode[NINODE - 1].i_hlink = -1; + for (i = 0; i < ninode-1; i++, ip++) + ip->i_hlink = i+1; + ip->i_hlink = -1; for (i = 0; i < INOHSZ; i++) inohash[i] = -1; } @@ -40,8 +41,8 @@ ihinit() */ struct inode * ifind(dev, ino) -dev_t dev; -ino_t ino; + dev_t dev; + ino_t ino; { register struct inode *ip; @@ -63,16 +64,14 @@ ino_t ino; * 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" */ struct inode * iget(dev, ino) -dev_t dev; -ino_t ino; + dev_t dev; + ino_t ino; { register struct inode *ip; register struct mount *mp; @@ -84,15 +83,15 @@ loop: slot = INOHASH(dev, ino); ip = &inode[inohash[slot]]; while (ip != &inode[-1]) { - if(ino == ip->i_number && dev == ip->i_dev) { - if((ip->i_flag&ILOCK) != 0) { + if (ino == ip->i_number && dev == ip->i_dev) { + if ((ip->i_flag&ILOCK) != 0) { ip->i_flag |= IWANT; sleep((caddr_t)ip, PINOD); goto loop; } - if((ip->i_flag&IMOUNT) != 0) { + if ((ip->i_flag&IMOUNT) != 0) { for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) - if(mp->m_inodp == ip) { + if (mp->m_inodp == ip) { dev = mp->m_dev; ino = ROOTINO; goto loop; @@ -105,8 +104,8 @@ loop: } ip = &inode[ip->i_hlink]; } - if(ifreel < 0) { - printf("Inode table overflow\n"); + if (ifreel < 0) { + tablefull("inode"); u.u_error = ENFILE; return(NULL); } @@ -123,7 +122,7 @@ loop: /* * Check I/O errors */ - if((bp->b_flags&B_ERROR) != 0) { + if ((bp->b_flags&B_ERROR) != 0) { brelse(bp); iput(ip); return(NULL); @@ -136,8 +135,8 @@ loop: } iexpand(ip, dp) -register struct inode *ip; -register struct dinode *dp; + register struct inode *ip; + register struct dinode *dp; { register char *p1, *p2; register int i; @@ -165,21 +164,21 @@ register struct dinode *dp; * truncate and deallocate the file. */ iput(ip) -register struct inode *ip; + register struct inode *ip; { register int i, x; register struct inode *jp; - if(ip->i_count == 1) { + if (ip->i_count == 1) { ip->i_flag |= ILOCK; - if(ip->i_nlink <= 0) { + if (ip->i_nlink <= 0) { itrunc(ip); ip->i_mode = 0; ip->i_flag |= IUPD|ICHG; ifree(ip->i_dev, ip->i_number); } - iupdat(ip, &time, &time); - prele(ip); + IUPDAT(ip, &time, &time, 0); + irele(ip); i = INOHASH(ip->i_dev, ip->i_number); x = ip - inode; if (inohash[i] == x) { @@ -199,7 +198,7 @@ done: ip->i_flag = 0; ip->i_number = 0; } else - prele(ip); + irele(ip); ip->i_count--; } @@ -208,18 +207,21 @@ done: * an inode structure. * If any is on, update the inode * with the current time. + * If waitfor is given, then must insure + * i/o order so wait for write to complete. */ -iupdat(ip, ta, tm) -register struct inode *ip; -time_t *ta, *tm; +iupdat(ip, ta, tm, waitfor) + register struct inode *ip; + time_t *ta, *tm; + int waitfor; { register struct buf *bp; struct dinode *dp; register char *p1, *p2; register int i; - if((ip->i_flag&(IUPD|IACC|ICHG)) != 0) { - if(getfs(ip->i_dev)->s_ronly) + if ((ip->i_flag&(IUPD|IACC|ICHG)) != 0) { + if (getfs(ip->i_dev)->s_ronly) return; bp = bread(ip->i_dev, itod(ip->i_number)); if (bp->b_flags & B_ERROR) { @@ -239,18 +241,20 @@ time_t *ta, *tm; *p1++ = *p2++; *p1++ = *p2++; *p1++ = *p2++; - if(*p2++ != 0 && (ip->i_mode&IFMT)!=IFMPC - && (ip->i_mode&IFMT)!=IFMPB) + if (*p2++ != 0) printf("iaddress > 2^24\n"); } - if(ip->i_flag&IACC) + if (ip->i_flag&IACC) dp->di_atime = *ta; - if(ip->i_flag&IUPD) + if (ip->i_flag&IUPD) dp->di_mtime = *tm; - if(ip->i_flag&ICHG) + if (ip->i_flag&ICHG) dp->di_ctime = time; ip->i_flag &= ~(IUPD|IACC|ICHG); - bdwrite(bp); + if (waitfor) + bwrite(bp); + else + bdwrite(bp); } } @@ -264,21 +268,37 @@ time_t *ta, *tm; * than FIFO. */ itrunc(ip) -register struct inode *ip; + register struct inode *ip; { register i; dev_t dev; daddr_t bn; + struct inode itmp; - if (ip->i_vfdcnt) - panic("itrunc"); i = ip->i_mode & IFMT; - if (i!=IFREG && i!=IFDIR) + if (i!=IFREG && i!=IFDIR && i!=IFLNK) return; + + /* + * Clean inode on disk before freeing blocks + * to insure no duplicates if system crashes. + */ + itmp = *ip; + itmp.i_size = 0; + for (i = 0; i < NADDR; i++) + itmp.i_un.i_addr[i] = 0; + itmp.i_flag |= ICHG|IUPD; + iupdat(&itmp, &time, &time, 1); + ip->i_flag &= ~(IUPD|IACC|ICHG); + + /* + * Now return blocks to free list... if machine + * crashes, they will be harmless MISSING blocks. + */ dev = ip->i_dev; for(i=NADDR-1; i>=0; i--) { bn = ip->i_un.i_addr[i]; - if(bn == (daddr_t)0) + if (bn == (daddr_t)0) continue; ip->i_un.i_addr[i] = (daddr_t)0; switch(i) { @@ -300,7 +320,10 @@ register struct inode *ip; } } ip->i_size = 0; - ip->i_flag |= ICHG|IUPD; + /* + * Inode was written and flags updated above. + * No need to modify flags here. + */ } tloop(dev, bn, f1, f2) @@ -314,7 +337,7 @@ daddr_t bn; bp = NULL; for(i=NINDIR-1; i>=0; i--) { - if(bp == NULL) { + if (bp == NULL) { bp = bread(dev, bn); if (bp->b_flags & B_ERROR) { brelse(bp); @@ -323,16 +346,16 @@ daddr_t bn; bap = bp->b_un.b_daddr; } nb = bap[i]; - if(nb == (daddr_t)0) + if (nb == (daddr_t)0) continue; - if(f1) { + if (f1) { brelse(bp); bp = NULL; tloop(dev, nb, f2, 0); } else free(dev, nb); } - if(bp != NULL) + if (bp != NULL) brelse(bp); free(dev, bn); } @@ -346,17 +369,23 @@ maknode(mode) register struct inode *ip; ip = ialloc(u.u_pdir->i_dev); - if(ip == NULL) { + if (ip == NULL) { iput(u.u_pdir); return(NULL); } ip->i_flag |= IACC|IUPD|ICHG; - if((mode&IFMT) == 0) + if ((mode&IFMT) == 0) mode |= IFREG; ip->i_mode = mode & ~u.u_cmask; ip->i_nlink = 1; ip->i_uid = u.u_uid; - ip->i_gid = u.u_gid; + ip->i_gid = u.u_pdir->i_gid; + + /* + * Make sure inode goes to disk before directory entry. + */ + iupdat(ip, &time, &time, 1); + wdir(ip); return(ip); } @@ -367,7 +396,7 @@ maknode(mode) * to a call to namei. */ wdir(ip) -struct inode *ip; + struct inode *ip; { u.u_dent.d_ino = ip->i_number; @@ -378,3 +407,37 @@ struct inode *ip; writei(u.u_pdir); iput(u.u_pdir); } + +#ifdef ilock +#undef ilock +#endif +#ifdef irele +#undef irele +#endif +/* + * Lock an inode. If its already locked, set the WANT bit and sleep. + */ +ilock(ip) + register struct inode *ip; +{ + + while (ip->i_flag&ILOCK) { + ip->i_flag |= IWANT; + sleep((caddr_t)ip, PINOD); + } + ip->i_flag |= ILOCK; +} + +/* + * Unlock an inode. If WANT bit is on, wakeup. + */ +irele(ip) + register struct inode *ip; +{ + + ip->i_flag &= ~ILOCK; + if (ip->i_flag&IWANT) { + ip->i_flag &= ~IWANT; + wakeup((caddr_t)ip); + } +}