- iupdat(ip, &time, &time, 1);
-
- wdir(ip);
- return(ip);
-}
-
-/*
- * Write a directory entry with
- * parameters left as side effects
- * to a call to namei.
- */
-wdir(ip)
- struct inode *ip;
-{
-
- u.u_dent.d_ino = ip->i_number;
- bcopy((caddr_t)u.u_dbuf, (caddr_t)u.u_dent.d_name, DIRSIZ);
- u.u_count = sizeof(struct direct);
- u.u_segflg = 1;
- u.u_base = (caddr_t)&u.u_dent;
- writei(u.u_pdir);
- iput(u.u_pdir);
+ bn = ip->i_db[lastblock];
+ if (bn != 0) {
+ off_t oldspace, newspace;
+
+ /*
+ * Calculate amount of space we're giving
+ * back as old block size minus new block size.
+ */
+ oldspace = blksize(fs, ip, lastblock);
+ ip->i_size = length;
+ newspace = blksize(fs, ip, lastblock);
+ if (newspace == 0)
+ panic("itrunc: newspace");
+ if (oldspace - newspace > 0) {
+ /*
+ * Block number of space to be free'd is
+ * the old block # plus the number of frags
+ * required for the storage we're keeping.
+ */
+ bn += numfrags(fs, newspace);
+ ffs_blkfree(ip, bn, oldspace - newspace);
+ blocksreleased += btodb(oldspace - newspace);
+ }
+ }
+done:
+/* BEGIN PARANOIA */
+ for (level = SINGLE; level <= TRIPLE; level++)
+ if (ip->i_ib[level] != oip->i_ib[level])
+ panic("itrunc1");
+ for (i = 0; i < NDADDR; i++)
+ if (ip->i_db[i] != oip->i_db[i])
+ panic("itrunc2");
+/* END PARANOIA */
+ oip->i_blocks -= blocksreleased;
+ if (oip->i_blocks < 0) /* sanity */
+ oip->i_blocks = 0;
+ oip->i_flag |= ICHG;
+#ifdef QUOTA
+ if (!getinoquota(oip))
+ (void) chkdq(oip, -blocksreleased, NOCRED, 0);
+#endif
+ return (allerror);