1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ffs_inode.c 7.49 (Berkeley) 05/13/92 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/mount.h> 13 #include <sys/proc.h> 14 #include <sys/file.h> 15 #include <sys/buf.h> 16 #include <sys/vnode.h> 17 #include <sys/kernel.h> 18 #include <sys/malloc.h> 19 20 #include <vm/vm.h> 21 22 #include <ufs/ufs/quota.h> 23 #include <ufs/ufs/inode.h> 24 #include <ufs/ufs/ufsmount.h> 25 #include <ufs/ufs/ufs_extern.h> 26 27 #include <ufs/ffs/fs.h> 28 #include <ufs/ffs/ffs_extern.h> 29 30 static int ffs_indirtrunc __P((struct inode *, daddr_t, daddr_t, int, long *)); 31 32 extern u_long nextgennumber; 33 34 int 35 ffs_init() 36 { 37 return (ufs_init()); 38 } 39 40 /* 41 * Look up a UFS dinode number to find its incore vnode. 42 * If it is not in core, read it in from the specified device. 43 * If it is in core, wait for the lock bit to clear, then 44 * return the inode locked. Detection and handling of mount 45 * points must be done by the calling routine. 46 */ 47 ffs_vget(mntp, ino, vpp) 48 struct mount *mntp; 49 ino_t ino; 50 struct vnode **vpp; 51 { 52 register struct fs *fs; 53 register struct inode *ip; 54 struct ufsmount *ump; 55 struct buf *bp; 56 struct dinode *dp; 57 struct vnode *vp; 58 union ihead *ih; 59 dev_t dev; 60 int i, type, error; 61 62 ump = VFSTOUFS(mntp); 63 dev = ump->um_dev; 64 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) 65 return (0); 66 67 /* Allocate a new vnode/inode. */ 68 if (error = getnewvnode(VT_UFS, mntp, &ffs_vnodeops, &vp)) { 69 *vpp = NULL; 70 return (error); 71 } 72 type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */ 73 MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK); 74 vp->v_data = ip; 75 ip->i_vnode = vp; 76 ip->i_flag = 0; 77 ip->i_devvp = 0; 78 ip->i_mode = 0; 79 ip->i_diroff = 0; 80 ip->i_lockf = 0; 81 ip->i_fs = fs = ump->um_fs; 82 ip->i_dev = dev; 83 ip->i_number = ino; 84 #ifdef QUOTA 85 for (i = 0; i < MAXQUOTAS; i++) 86 ip->i_dquot[i] = NODQUOT; 87 #endif 88 /* 89 * Put it onto its hash chain and lock it so that other requests for 90 * this inode will block if they arrive while we are sleeping waiting 91 * for old data structures to be purged or for the contents of the 92 * disk portion of this inode to be read. 93 */ 94 ufs_ihashins(ip); 95 96 /* Read in the disk contents for the inode, copy into the inode. */ 97 if (error = bread(ump->um_devvp, fsbtodb(fs, itod(fs, ino)), 98 (int)fs->fs_bsize, NOCRED, &bp)) { 99 /* 100 * The inode does not contain anything useful, so it would 101 * be misleading to leave it on its hash chain. It will be 102 * returned to the free list by ufs_iput(). 103 */ 104 remque(ip); 105 ip->i_forw = ip; 106 ip->i_back = ip; 107 108 /* Unlock and discard unneeded inode. */ 109 ufs_iput(ip); 110 brelse(bp); 111 *vpp = NULL; 112 return (error); 113 } 114 dp = bp->b_un.b_dino; 115 dp += itoo(fs, ino); 116 ip->i_din = *dp; 117 brelse(bp); 118 119 /* 120 * Initialize the vnode from the inode, check for aliases. 121 * Note that the underlying vnode may have changed. 122 */ 123 if (error = ufs_vinit(mntp, &ffs_specops, FFS_FIFOOPS, &vp)) { 124 ufs_iput(ip); 125 *vpp = NULL; 126 return (error); 127 } 128 /* 129 * Finish inode initialization now that aliasing has been resolved. 130 */ 131 ip->i_devvp = ump->um_devvp; 132 VREF(ip->i_devvp); 133 /* 134 * Set up a generation number for this inode if it does not 135 * already have one. This should only happen on old filesystems. 136 */ 137 if (ip->i_gen == 0) { 138 if (++nextgennumber < (u_long)time.tv_sec) 139 nextgennumber = time.tv_sec; 140 ip->i_gen = nextgennumber; 141 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 142 ip->i_flag |= IMOD; 143 } 144 *vpp = vp; 145 return (0); 146 } 147 148 /* 149 * Update the access, modified, and inode change times as specified 150 * by the IACC, IUPD, and ICHG flags respectively. The IMOD flag 151 * is used to specify that the inode needs to be updated but that 152 * the times have already been set. The access and modified times 153 * are taken from the second and third parameters; the inode change 154 * time is always taken from the current time. If waitfor is set, 155 * then wait for the disk write of the inode to complete. 156 */ 157 int 158 ffs_update(vp, ta, tm, waitfor) 159 register struct vnode *vp; 160 struct timeval *ta, *tm; 161 int waitfor; 162 { 163 struct buf *bp; 164 struct inode *ip; 165 struct dinode *dp; 166 register struct fs *fs; 167 int error; 168 169 if (vp->v_mount->mnt_flag & MNT_RDONLY) 170 return (0); 171 ip = VTOI(vp); 172 if ((ip->i_flag & (IUPD|IACC|ICHG|IMOD)) == 0) 173 return (0); 174 if (ip->i_flag&IACC) 175 ip->i_atime.tv_sec = ta->tv_sec; 176 if (ip->i_flag&IUPD) { 177 ip->i_mtime.tv_sec = tm->tv_sec; 178 INCRQUAD(ip->i_modrev); 179 } 180 if (ip->i_flag&ICHG) 181 ip->i_ctime.tv_sec = time.tv_sec; 182 ip->i_flag &= ~(IUPD|IACC|ICHG|IMOD); 183 184 fs = ip->i_fs; 185 if (error = bread(ip->i_devvp, fsbtodb(fs, itod(fs, ip->i_number)), 186 (int)fs->fs_bsize, NOCRED, &bp)) { 187 brelse(bp); 188 return (error); 189 } 190 dp = bp->b_un.b_dino + itoo(fs, ip->i_number); 191 *dp = ip->i_din; 192 if (waitfor) 193 return (bwrite(bp)); 194 else { 195 bdwrite(bp); 196 return (0); 197 } 198 } 199 200 #define SINGLE 0 /* index of single indirect block */ 201 #define DOUBLE 1 /* index of double indirect block */ 202 #define TRIPLE 2 /* index of triple indirect block */ 203 /* 204 * Truncate the inode ip to at most length size. Free affected disk 205 * blocks -- the blocks of the file are removed in reverse order. 206 * 207 * NB: triple indirect blocks are untested. 208 */ 209 ffs_truncate(ovp, length, flags, cred) 210 register struct vnode *ovp; 211 off_t length; 212 int flags; 213 struct ucred *cred; 214 { 215 register daddr_t lastblock; 216 register struct inode *oip; 217 daddr_t bn, lbn, lastiblock[NIADDR]; 218 register struct fs *fs; 219 register struct inode *ip; 220 struct buf *bp; 221 int offset, size, level; 222 long count, nblocks, blocksreleased = 0; 223 register int i; 224 int aflags, error, allerror; 225 struct inode tip; 226 off_t osize; 227 228 vnode_pager_setsize(ovp, (u_long)length); 229 oip = VTOI(ovp); 230 if (oip->i_size <= length) { 231 oip->i_flag |= ICHG|IUPD; 232 error = ffs_update(ovp, &time, &time, 1); 233 return (error); 234 } 235 /* 236 * Calculate index into inode's block list of 237 * last direct and indirect blocks (if any) 238 * which we want to keep. Lastblock is -1 when 239 * the file is truncated to 0. 240 */ 241 fs = oip->i_fs; 242 lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1; 243 lastiblock[SINGLE] = lastblock - NDADDR; 244 lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs); 245 lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs); 246 nblocks = btodb(fs->fs_bsize); 247 /* 248 * Update the size of the file. If the file is not being 249 * truncated to a block boundry, the contents of the 250 * partial block following the end of the file must be 251 * zero'ed in case it ever become accessable again because 252 * of subsequent file growth. 253 */ 254 osize = oip->i_size; 255 offset = blkoff(fs, length); 256 if (offset == 0) { 257 oip->i_size = length; 258 } else { 259 lbn = lblkno(fs, length); 260 aflags = B_CLRBUF; 261 if (flags & IO_SYNC) 262 aflags |= B_SYNC; 263 #ifdef QUOTA 264 if (error = getinoquota(oip)) 265 return (error); 266 #endif 267 if (error = ffs_balloc(oip, lbn, offset, cred, &bp, aflags)) 268 return (error); 269 oip->i_size = length; 270 size = blksize(fs, oip, lbn); 271 (void) vnode_pager_uncache(ovp); 272 bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset)); 273 allocbuf(bp, size); 274 if (flags & IO_SYNC) 275 bwrite(bp); 276 else 277 bdwrite(bp); 278 } 279 /* 280 * Update file and block pointers on disk before we start freeing 281 * blocks. If we crash before free'ing blocks below, the blocks 282 * will be returned to the free list. lastiblock values are also 283 * normalized to -1 for calls to ffs_indirtrunc below. 284 */ 285 tip = *oip; 286 tip.i_size = osize; 287 for (level = TRIPLE; level >= SINGLE; level--) 288 if (lastiblock[level] < 0) { 289 oip->i_ib[level] = 0; 290 lastiblock[level] = -1; 291 } 292 for (i = NDADDR - 1; i > lastblock; i--) 293 oip->i_db[i] = 0; 294 oip->i_flag |= ICHG|IUPD; 295 vinvalbuf(ovp, (length > 0)); 296 allerror = ffs_update(ovp, &time, &time, MNT_WAIT); 297 298 /* 299 * Indirect blocks first. 300 */ 301 ip = &tip; 302 for (level = TRIPLE; level >= SINGLE; level--) { 303 bn = ip->i_ib[level]; 304 if (bn != 0) { 305 error = ffs_indirtrunc(ip, 306 bn, lastiblock[level], level, &count); 307 if (error) 308 allerror = error; 309 blocksreleased += count; 310 if (lastiblock[level] < 0) { 311 ip->i_ib[level] = 0; 312 ffs_blkfree(ip, bn, fs->fs_bsize); 313 blocksreleased += nblocks; 314 } 315 } 316 if (lastiblock[level] >= 0) 317 goto done; 318 } 319 320 /* 321 * All whole direct blocks or frags. 322 */ 323 for (i = NDADDR - 1; i > lastblock; i--) { 324 register long bsize; 325 326 bn = ip->i_db[i]; 327 if (bn == 0) 328 continue; 329 ip->i_db[i] = 0; 330 bsize = blksize(fs, ip, i); 331 ffs_blkfree(ip, bn, bsize); 332 blocksreleased += btodb(bsize); 333 } 334 if (lastblock < 0) 335 goto done; 336 337 /* 338 * Finally, look for a change in size of the 339 * last direct block; release any frags. 340 */ 341 bn = ip->i_db[lastblock]; 342 if (bn != 0) { 343 long oldspace, newspace; 344 345 /* 346 * Calculate amount of space we're giving 347 * back as old block size minus new block size. 348 */ 349 oldspace = blksize(fs, ip, lastblock); 350 ip->i_size = length; 351 newspace = blksize(fs, ip, lastblock); 352 if (newspace == 0) 353 panic("itrunc: newspace"); 354 if (oldspace - newspace > 0) { 355 /* 356 * Block number of space to be free'd is 357 * the old block # plus the number of frags 358 * required for the storage we're keeping. 359 */ 360 bn += numfrags(fs, newspace); 361 ffs_blkfree(ip, bn, oldspace - newspace); 362 blocksreleased += btodb(oldspace - newspace); 363 } 364 } 365 done: 366 /* BEGIN PARANOIA */ 367 for (level = SINGLE; level <= TRIPLE; level++) 368 if (ip->i_ib[level] != oip->i_ib[level]) 369 panic("itrunc1"); 370 for (i = 0; i < NDADDR; i++) 371 if (ip->i_db[i] != oip->i_db[i]) 372 panic("itrunc2"); 373 /* END PARANOIA */ 374 oip->i_blocks -= blocksreleased; 375 if (oip->i_blocks < 0) /* sanity */ 376 oip->i_blocks = 0; 377 oip->i_flag |= ICHG; 378 #ifdef QUOTA 379 if (!getinoquota(oip)) 380 (void) chkdq(oip, -blocksreleased, NOCRED, 0); 381 #endif 382 return (allerror); 383 } 384 385 /* 386 * Release blocks associated with the inode ip and stored in the indirect 387 * block bn. Blocks are free'd in LIFO order up to (but not including) 388 * lastbn. If level is greater than SINGLE, the block is an indirect block 389 * and recursive calls to indirtrunc must be used to cleanse other indirect 390 * blocks. 391 * 392 * NB: triple indirect blocks are untested. 393 */ 394 static int 395 ffs_indirtrunc(ip, bn, lastbn, level, countp) 396 register struct inode *ip; 397 daddr_t bn, lastbn; 398 int level; 399 long *countp; 400 { 401 register int i; 402 struct buf *bp; 403 register struct fs *fs = ip->i_fs; 404 register daddr_t *bap; 405 daddr_t *copy, nb, last; 406 long blkcount, factor; 407 int nblocks, blocksreleased = 0; 408 int error, allerror = 0; 409 410 /* 411 * Calculate index in current block of last 412 * block to be kept. -1 indicates the entire 413 * block so we need not calculate the index. 414 */ 415 factor = 1; 416 for (i = SINGLE; i < level; i++) 417 factor *= NINDIR(fs); 418 last = lastbn; 419 if (lastbn > 0) 420 last /= factor; 421 nblocks = btodb(fs->fs_bsize); 422 /* 423 * Get buffer of block pointers, zero those 424 * entries corresponding to blocks to be free'd, 425 * and update on disk copy first. 426 */ 427 error = bread(ip->i_devvp, fsbtodb(fs, bn), (int)fs->fs_bsize, 428 NOCRED, &bp); 429 if (error) { 430 brelse(bp); 431 *countp = 0; 432 return (error); 433 } 434 bap = bp->b_un.b_daddr; 435 MALLOC(copy, daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK); 436 bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->fs_bsize); 437 bzero((caddr_t)&bap[last + 1], 438 (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t)); 439 if (last == -1) 440 bp->b_flags |= B_INVAL; 441 error = bwrite(bp); 442 if (error) 443 allerror = error; 444 bap = copy; 445 446 /* 447 * Recursively free totally unused blocks. 448 */ 449 for (i = NINDIR(fs) - 1; i > last; i--) { 450 nb = bap[i]; 451 if (nb == 0) 452 continue; 453 if (level > SINGLE) { 454 if (error = ffs_indirtrunc(ip, 455 nb, (daddr_t)-1, level - 1, &blkcount)) 456 allerror = error; 457 blocksreleased += blkcount; 458 } 459 ffs_blkfree(ip, nb, fs->fs_bsize); 460 blocksreleased += nblocks; 461 } 462 463 /* 464 * Recursively free last partial block. 465 */ 466 if (level > SINGLE && lastbn >= 0) { 467 last = lastbn % factor; 468 nb = bap[i]; 469 if (nb != 0) { 470 if (error = 471 ffs_indirtrunc(ip, nb, last, level - 1, &blkcount)) 472 allerror = error; 473 blocksreleased += blkcount; 474 } 475 } 476 FREE(copy, M_TEMP); 477 *countp = blocksreleased; 478 return (allerror); 479 } 480