- }
- IUPDAT(ip, &time, &time, 0);
- iunlock(ip);
- ip->i_flag = 0;
- /*
- * Put the inode on the end of the free list.
- * Possibly in some cases it would be better to
- * put the inode at the head of the free list,
- * (eg: where i_mode == 0 || i_number == 0)
- * but I will think about that later .. kre
- * (i_number is rarely 0 - only after an i/o error in iget,
- * where i_mode == 0, the inode will probably be wanted
- * again soon for an ialloc, so possibly we should keep it)
- */
- if (ifreeh) {
- *ifreet = ip;
- ip->i_freeb = ifreet;
- } else {
- ifreeh = ip;
- ip->i_freeb = &ifreeh;
- }
- ip->i_freef = NULL;
- ifreet = &ip->i_freef;
- }
- ip->i_count--;
-}
-
-/*
- * Check accessed and update flags on
- * 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, waitfor)
- register struct inode *ip;
- struct timeval *ta, *tm;
- int waitfor;
-{
- register struct buf *bp;
- struct dinode *dp;
- register struct fs *fp;
-
- fp = ip->i_fs;
- if ((ip->i_flag & (IUPD|IACC|ICHG)) != 0) {
- if (fp->fs_ronly)
- return;
- bp = bread(ip->i_dev, fsbtodb(fp, itod(fp, ip->i_number)),
- (int)fp->fs_bsize);
- if (bp->b_flags & B_ERROR) {
- brelse(bp);
- return;
- }
- if (ip->i_flag&IACC)
- ip->i_atime = ta->tv_sec;
- if (ip->i_flag&IUPD)
- ip->i_mtime = tm->tv_sec;
- if (ip->i_flag&ICHG)
- ip->i_ctime = time.tv_sec;
- ip->i_flag &= ~(IUPD|IACC|ICHG);
- dp = bp->b_un.b_dino + itoo(fp, ip->i_number);
- dp->di_ic = ip->i_ic;
- if (waitfor)
- bwrite(bp);
- else
- bdwrite(bp);
- }
-}
-
-#define SINGLE 0 /* index of single indirect block */
-#define DOUBLE 1 /* index of double indirect block */
-#define TRIPLE 2 /* index of triple indirect block */
-/*
- * Truncate the inode ip to at most
- * length size. Free affected disk
- * blocks -- the blocks of the file
- * are removed in reverse order.
- *
- * NB: triple indirect blocks are untested.
- */
-itrunc(oip, length)
- struct inode *oip;
- u_long length;
-{
- register i;
- register daddr_t lastblock;
- daddr_t bn, lastiblock[NIADDR];
- register struct fs *fs;
- register struct inode *ip;
- struct inode tip;
- long blocksreleased = 0, nblocks;
- long indirtrunc();
- int level;
-
- if (oip->i_size <= length) {
- oip->i_flag |= ICHG|IUPD;
- iupdat(oip, &time, &time, 1);
- return;