- 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) {
- brelse(bp);
- return;
- }
- dp = bp->b_un.b_dino;
- dp += itoo(ip->i_number);
- dp->di_mode = 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;
- p1 = (char *)dp->di_addr;
- p2 = (char *)ip->i_un.i_addr;
- for(i=0; i<NADDR; i++) {
- *p1++ = *p2++;
- *p1++ = *p2++;
- *p1++ = *p2++;
- if(*p2++ != 0 && (ip->i_mode&IFMT)!=IFMPC
- && (ip->i_mode&IFMT)!=IFMPB)
- printf("iaddress > 2^24\n");
- }
- if(ip->i_flag&IACC)
- dp->di_atime = *ta;
- if(ip->i_flag&IUPD)
- dp->di_mtime = *tm;
- if(ip->i_flag&ICHG)
- dp->di_ctime = time;
- ip->i_flag &= ~(IUPD|IACC|ICHG);
- if (waitfor)
+ vnode_pager_setsize(ovp, length);
+ oip = VTOI(ovp);
+ if (oip->i_size <= length) {
+ oip->i_flag |= ICHG|IUPD;
+ error = ffs_update(ovp, &time, &time, 1);
+ return (error);
+ }
+ /*
+ * Calculate index into inode's block list of
+ * last direct and indirect blocks (if any)
+ * which we want to keep. Lastblock is -1 when
+ * the file is truncated to 0.
+ */
+ fs = oip->i_fs;
+ lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1;
+ lastiblock[SINGLE] = lastblock - NDADDR;
+ lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs);
+ lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs);
+ nblocks = btodb(fs->fs_bsize);
+ /*
+ * Update the size of the file. If the file is not being
+ * truncated to a block boundry, the contents of the
+ * partial block following the end of the file must be
+ * zero'ed in case it ever become accessable again because
+ * of subsequent file growth.
+ */
+ osize = oip->i_size;
+ offset = blkoff(fs, length);
+ if (offset == 0) {
+ oip->i_size = length;
+ } else {
+ lbn = lblkno(fs, length);
+ aflags = B_CLRBUF;
+ if (flags & IO_SYNC)
+ aflags |= B_SYNC;
+#ifdef QUOTA
+ if (error = getinoquota(oip))
+ return (error);
+#endif
+ if (error = ffs_balloc(oip, lbn, offset, &bp, aflags))
+ return (error);
+ oip->i_size = length;
+ size = blksize(fs, oip, lbn);
+ (void) vnode_pager_uncache(ITOV(oip));
+ bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset));
+ allocbuf(bp, size);
+ if (flags & IO_SYNC)