1 /* lfs_inode.c 4.31 82/11/13 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/mount.h" 6 #include "../h/dir.h" 7 #include "../h/user.h" 8 #include "../h/inode.h" 9 #include "../h/fs.h" 10 #include "../h/conf.h" 11 #include "../h/buf.h" 12 #ifdef QUOTA 13 #include "../h/quota.h" 14 #endif 15 #include "../h/kernel.h" 16 17 #define INOHSZ 63 18 #if ((INOHSZ&(INOHSZ-1)) == 0) 19 #define INOHASH(dev,ino) (((dev)+(ino))&(INOHSZ-1)) 20 #else 21 #define INOHASH(dev,ino) (((dev)+(ino))%INOHSZ) 22 #endif 23 24 union ihead { /* inode LRU cache, Chris Maltby */ 25 union ihead *ih_head[2]; 26 struct inode *ih_chain[2]; 27 } ihead[INOHSZ]; 28 29 struct inode *ifreeh, **ifreet; 30 31 /* 32 * Initialize hash links for inodes 33 * and build inode free list. 34 */ 35 ihinit() 36 { 37 register int i; 38 register struct inode *ip = inode; 39 register union ihead *ih = ihead; 40 41 for (i = INOHSZ; --i >= 0; ih++) { 42 ih->ih_head[0] = ih; 43 ih->ih_head[1] = ih; 44 } 45 ifreeh = ip; 46 ifreet = &ip->i_freef; 47 ip->i_freeb = &ifreeh; 48 ip->i_forw = ip; 49 ip->i_back = ip; 50 for (i = ninode; --i > 0; ) { 51 ++ip; 52 ip->i_forw = ip; 53 ip->i_back = ip; 54 *ifreet = ip; 55 ip->i_freeb = ifreet; 56 ifreet = &ip->i_freef; 57 } 58 ip->i_freef = NULL; 59 } 60 61 #ifdef notdef 62 /* 63 * Find an inode if it is incore. 64 * This is the equivalent, for inodes, 65 * of ``incore'' in bio.c or ``pfind'' in subr.c. 66 */ 67 struct inode * 68 ifind(dev, ino) 69 dev_t dev; 70 ino_t ino; 71 { 72 register struct inode *ip; 73 register union ihead *ih; 74 75 ih = &ihead[INOHASH(dev, ino)]; 76 for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw) 77 if (ino==ip->i_number && dev==ip->i_dev) 78 return (ip); 79 return ((struct inode *)0); 80 } 81 #endif notdef 82 83 /* 84 * Look up an inode by device,inumber. 85 * If it is in core (in the inode structure), 86 * honor the locking protocol. 87 * If it is not in core, read it in from the 88 * specified device. 89 * If the inode is mounted on, perform 90 * the indicated indirection. 91 * In all cases, a pointer to a locked 92 * inode structure is returned. 93 * 94 * panic: no imt -- if the mounted file 95 * system is not in the mount table. 96 * "cannot happen" 97 */ 98 struct inode * 99 iget(dev, fs, ino) 100 dev_t dev; 101 register struct fs *fs; 102 ino_t ino; 103 { 104 register struct inode *ip; 105 register union ihead *ih; 106 register struct mount *mp; 107 register struct buf *bp; 108 register struct dinode *dp; 109 register struct inode *iq; 110 111 loop: 112 if (getfs(dev) != fs) 113 panic("iget: bad fs"); 114 ih = &ihead[INOHASH(dev, ino)]; 115 for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw) 116 if (ino == ip->i_number && dev == ip->i_dev) { 117 if ((ip->i_flag&ILOCKED) != 0) { 118 ip->i_flag |= IWANT; 119 sleep((caddr_t)ip, PINOD); 120 goto loop; 121 } 122 if ((ip->i_flag&IMOUNT) != 0) { 123 for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++) 124 if(mp->m_inodp == ip) { 125 dev = mp->m_dev; 126 fs = mp->m_bufp->b_un.b_fs; 127 ino = ROOTINO; 128 goto loop; 129 } 130 panic("no imt"); 131 } 132 if (ip->i_count == 0) { /* ino on free list */ 133 if (iq = ip->i_freef) 134 iq->i_freeb = ip->i_freeb; 135 else 136 ifreet = ip->i_freeb; 137 *ip->i_freeb = iq; 138 ip->i_freef = NULL; 139 ip->i_freeb = NULL; 140 } 141 ip->i_count++; 142 ip->i_flag |= ILOCKED; 143 return(ip); 144 } 145 146 if ((ip = ifreeh) == NULL) { 147 tablefull("inode"); 148 u.u_error = ENFILE; 149 return(NULL); 150 } 151 if (iq = ip->i_freef) 152 iq->i_freeb = &ifreeh; 153 ifreeh = iq; 154 ip->i_freef = NULL; 155 ip->i_freeb = NULL; 156 /* 157 * Now to take inode off the hash chain it was on 158 * (initially, or after an iflush, it is on a "hash chain" 159 * consisting entirely of itself, and pointed to by no-one, 160 * but that doesn't matter), and put it on the chain for 161 * its new (ino, dev) pair 162 */ 163 remque(ip); 164 insque(ip, ih); 165 #ifdef QUOTA 166 dqrele(ip->i_dquot); 167 #endif 168 ip->i_dev = dev; 169 ip->i_fs = fs; 170 ip->i_number = ino; 171 ip->i_flag = ILOCKED; 172 ip->i_count++; 173 ip->i_lastr = 0; 174 bp = bread(dev, fsbtodb(fs, itod(fs, ino)), (int)fs->fs_bsize); 175 /* 176 * Check I/O errors 177 */ 178 if ((bp->b_flags&B_ERROR) != 0) { 179 brelse(bp); 180 /* 181 * the inode doesn't contain anything useful, so it would 182 * be misleading to leave it on its hash chain. 183 * 'iput' will take care of putting it back on the free list. 184 */ 185 remque(ip); 186 ip->i_forw = ip; 187 ip->i_back = ip; 188 /* 189 * we also loose its inumber, just in case (as iput 190 * doesn't do that any more) - but as it isn't on its 191 * hash chain, I doubt if this is really necessary .. kre 192 * (probably the two methods are interchangable) 193 */ 194 ip->i_number = 0; 195 #ifdef QUOTA 196 ip->i_dquot = NODQUOT; 197 #endif 198 iput(ip); 199 return(NULL); 200 } 201 dp = bp->b_un.b_dino; 202 dp += itoo(fs, ino); 203 ip->i_ic = dp->di_ic; 204 brelse(bp); 205 #ifdef QUOTA 206 if (ip->i_mode == 0) 207 ip->i_dquot = NODQUOT; 208 else 209 ip->i_dquot = inoquota(ip); 210 #endif 211 return (ip); 212 } 213 214 /* 215 * Decrement reference count of 216 * an inode structure. 217 * On the last reference, 218 * write the inode out and if necessary, 219 * truncate and deallocate the file. 220 */ 221 iput(ip) 222 register struct inode *ip; 223 { 224 225 if ((ip->i_flag & ILOCKED) == 0) 226 panic("iput"); 227 iunlock(ip); 228 irele(ip); 229 } 230 231 irele(ip) 232 register struct inode *ip; 233 { 234 int mode; 235 236 if (ip->i_count == 1) { 237 ip->i_flag |= ILOCKED; 238 if (ip->i_nlink <= 0) { 239 itrunc(ip, (u_long)0); 240 mode = ip->i_mode; 241 ip->i_mode = 0; 242 ip->i_rdev = 0; 243 ip->i_flag |= IUPD|ICHG; 244 ifree(ip, ip->i_number, mode); 245 #ifdef QUOTA 246 (void)chkiq(ip->i_dev, ip, ip->i_uid, 0); 247 dqrele(ip->i_dquot); 248 ip->i_dquot = NODQUOT; 249 #endif 250 } 251 IUPDAT(ip, &time, &time, 0); 252 iunlock(ip); 253 ip->i_flag = 0; 254 /* 255 * Put the inode on the end of the free list. 256 * Possibly in some cases it would be better to 257 * put the inode at the head of the free list, 258 * (eg: where i_mode == 0 || i_number == 0) 259 * but I will think about that later .. kre 260 * (i_number is rarely 0 - only after an i/o error in iget, 261 * where i_mode == 0, the inode will probably be wanted 262 * again soon for an ialloc, so possibly we should keep it) 263 */ 264 if (ifreeh) { 265 *ifreet = ip; 266 ip->i_freeb = ifreet; 267 } else { 268 ifreeh = ip; 269 ip->i_freeb = &ifreeh; 270 } 271 ip->i_freef = NULL; 272 ifreet = &ip->i_freef; 273 } 274 ip->i_count--; 275 } 276 277 /* 278 * Check accessed and update flags on 279 * an inode structure. 280 * If any is on, update the inode 281 * with the current time. 282 * If waitfor is given, then must insure 283 * i/o order so wait for write to complete. 284 */ 285 iupdat(ip, ta, tm, waitfor) 286 register struct inode *ip; 287 struct timeval *ta, *tm; 288 int waitfor; 289 { 290 register struct buf *bp; 291 struct dinode *dp; 292 register struct fs *fp; 293 294 fp = ip->i_fs; 295 if ((ip->i_flag & (IUPD|IACC|ICHG)) != 0) { 296 if (fp->fs_ronly) 297 return; 298 bp = bread(ip->i_dev, fsbtodb(fp, itod(fp, ip->i_number)), 299 (int)fp->fs_bsize); 300 if (bp->b_flags & B_ERROR) { 301 brelse(bp); 302 return; 303 } 304 if (ip->i_flag&IACC) 305 ip->i_atime = ta->tv_sec; 306 if (ip->i_flag&IUPD) 307 ip->i_mtime = tm->tv_sec; 308 if (ip->i_flag&ICHG) 309 ip->i_ctime = time.tv_sec; 310 ip->i_flag &= ~(IUPD|IACC|ICHG); 311 dp = bp->b_un.b_dino + itoo(fp, ip->i_number); 312 dp->di_ic = ip->i_ic; 313 if (waitfor) 314 bwrite(bp); 315 else 316 bdwrite(bp); 317 } 318 } 319 320 /* 321 * Truncate the inode ip to at most 322 * length size. Free affected disk 323 * blocks -- the blocks of the file 324 * are removed in reverse order. 325 */ 326 itrunc(ip, length) 327 register struct inode *ip; 328 u_long length; 329 { 330 register i; 331 register daddr_t lastblock; 332 daddr_t bn, lastdiblock, lastsiblock; 333 register struct fs *fs; 334 int j; 335 #ifdef QUOTA 336 long blocksreleased = 0, nblocks; 337 long indirtrunc(); 338 #endif 339 340 if (ip->i_size <= length) 341 return; 342 #ifdef notdef 343 /* this is superfluous given size check above */ 344 i = ip->i_mode & IFMT; 345 if (i != IFREG && i != IFDIR && i != IFLNK) { 346 printf("itrunc: i# %d, size %d\n", ip->i_number, ip->i_size); 347 return; 348 } 349 #endif 350 /* 351 * Update size of file on disk before 352 * we start freeing blocks. If we crash 353 * while free'ing blocks below, the file 354 * size will be believed and the blocks 355 * returned to the free list. 356 * After updating the copy on disk we 357 * put the old size back so macros like 358 * blksize will work. 359 */ 360 j = ip->i_size; 361 ip->i_size = length; 362 ip->i_flag |= ICHG|IUPD; 363 iupdat(ip, &time, &time, 1); 364 ip->i_size = j; 365 366 /* 367 * Calculate last direct, single indirect and 368 * double indirect block (if any) which we want 369 * to keep. Lastblock is -1 when the file is 370 * truncated to 0. 371 */ 372 fs = ip->i_fs; 373 lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1; 374 lastsiblock = lastblock - NDADDR; 375 lastdiblock = lastsiblock - NINDIR(fs); 376 #ifdef QUOTA 377 nblocks = fs->fs_bsize / DEV_BSIZE; 378 #endif 379 /* 380 * Double indirect block first 381 */ 382 bn = ip->i_ib[NIADDR - 1]; 383 if (bn != 0) { 384 /* 385 * If lastdiblock is negative, it's value 386 * is meaningless; in this case we set it to 387 * -NINDIR(fs) so calculations performed in 388 * indirtrunc come out right. 389 */ 390 if (lastdiblock < 0) 391 lastdiblock -= lastsiblock; 392 #ifdef QUOTA 393 blocksreleased += 394 #endif 395 indirtrunc(ip, bn, lastdiblock, 1); 396 if (lastdiblock < 0) { 397 ip->i_ib[NIADDR - 1] = 0; 398 free(ip, bn, (off_t)fs->fs_bsize); 399 #ifdef QUOTA 400 blocksreleased += nblocks; 401 #endif 402 } 403 } 404 if (lastdiblock >= 0) 405 goto done; 406 /* 407 * Single indirect blocks second. 408 * First, those which can be totally 409 * zapped, then possibly one which 410 * needs to be partially cleared. 411 */ 412 j = lastsiblock < 0 ? -1 : lastsiblock / NINDIR(fs); 413 for (i = NIADDR - 2; i > j; i--) { 414 bn = ip->i_ib[i]; 415 if (bn != 0) { 416 #ifdef QUOTA 417 blocksreleased += nblocks + 418 #endif 419 indirtrunc(ip, bn, (daddr_t)-1, 0); 420 ip->i_ib[i] = 0; 421 free(ip, bn, (off_t)fs->fs_bsize); 422 } 423 } 424 if (lastsiblock >= 0) { 425 bn = ip->i_ib[j]; 426 if (bn != 0) 427 #ifdef QUOTA 428 blocksreleased += 429 #endif 430 indirtrunc(ip, bn, lastsiblock, 0); 431 goto done; 432 } 433 /* 434 * All whole direct blocks. 435 */ 436 for (i = NDADDR - 1; i > lastblock; i--) { 437 register int size; 438 439 bn = ip->i_db[i]; 440 if (bn == 0) 441 continue; 442 ip->i_db[i] = 0; 443 size = (off_t)blksize(fs, ip, i); 444 free(ip, bn, size); 445 #ifdef QUOTA 446 blocksreleased += size / DEV_BSIZE; 447 #endif 448 } 449 /* 450 * Finally, look for a change in size of the 451 * last direct block; release any frags. 452 */ 453 if (lastblock >= 0 && ip->i_db[lastblock] != 0) { 454 /* 455 * Calculate amount of space we're giving 456 * back as old block size minus new block size. 457 */ 458 i = blksize(fs, ip, lastblock); 459 ip->i_size = length; 460 i = i - blksize(fs, ip, lastblock); 461 if (i > 0) { 462 /* 463 * Block number of space to be free'd is 464 * the old block # plus the number of frags 465 * required for the storage we're keeping. 466 */ 467 bn = ip->i_db[lastblock] + 468 numfrags(fs, fs->fs_bsize - i); 469 free(ip, bn, i); 470 #ifdef QUOTA 471 blocksreleased += i / DEV_BSIZE; 472 #endif 473 } 474 } 475 done: 476 /* 477 * Finished free'ing blocks, complete 478 * inode update to reflect new length. 479 */ 480 #ifdef QUOTA 481 (void) chkdq(ip, -blocksreleased, 0); 482 #endif 483 ip->i_size = length; 484 ip->i_flag |= ICHG|IUPD; 485 iupdat(ip, &time, &time, 1); 486 } 487 488 /* 489 * Release blocks associated with the inode ip and 490 * stored in the indirect block bn. Blocks are free'd 491 * in LIFO order up to (but not including) lastbn. If 492 * doubleindirect is indicated, this block is a double 493 * indirect block and recursive calls to indirtrunc must 494 * be used to cleanse single indirect blocks instead of 495 * a simple free. 496 */ 497 #ifdef QUOTA 498 long 499 #endif 500 indirtrunc(ip, bn, lastbn, doubleindirect) 501 register struct inode *ip; 502 daddr_t bn, lastbn; 503 int doubleindirect; 504 { 505 register int i; 506 struct buf *bp; 507 register daddr_t *bap; 508 register struct fs *fs; 509 daddr_t nb, last; 510 #ifdef QUOTA 511 int blocksreleased = 0, nblocks; 512 #endif 513 514 bp = NULL; 515 fs = ip->i_fs; 516 last = lastbn; 517 if (doubleindirect) 518 last /= NINDIR(fs); 519 #ifdef QUOTA 520 nblocks = fs->fs_bsize / DEV_BSIZE; 521 #endif 522 for (i = NINDIR(fs) - 1; i > last; i--) { 523 if (bp == NULL) { 524 struct buf *copy; 525 526 copy = geteblk((int)fs->fs_bsize); 527 bp = bread(ip->i_dev, fsbtodb(fs, bn), 528 (int)fs->fs_bsize); 529 if (bp->b_flags&B_ERROR) { 530 brelse(copy); 531 brelse(bp); 532 return (NULL); 533 } 534 bap = bp->b_un.b_daddr; 535 /* 536 * Update pointers before freeing blocks. 537 * If we crash before freeing the blocks 538 * they'll be recovered as missing. 539 */ 540 bcopy((caddr_t)bap, (caddr_t)copy->b_un.b_daddr, 541 (u_int)fs->fs_bsize); 542 bzero((caddr_t)&bap[last + 1], 543 (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t)); 544 bwrite(bp); 545 bp = copy, bap = bp->b_un.b_daddr; 546 } 547 nb = bap[i]; 548 if (nb == 0) 549 continue; 550 if (doubleindirect) 551 #ifdef QUOTA 552 blocksreleased += 553 #endif 554 indirtrunc(ip, nb, (daddr_t)-1, 0); 555 free(ip, nb, (int)fs->fs_bsize); 556 #ifdef QUOTA 557 blocksreleased += nblocks; 558 #endif 559 } 560 if (doubleindirect && lastbn >= 0) { 561 last = lastbn % NINDIR(fs); 562 if (bp == NULL) 563 panic("indirtrunc"); 564 nb = bap[i]; 565 if (nb != 0) 566 #ifdef QUOTA 567 blocksreleased += 568 #endif 569 indirtrunc(ip, nb, last, 0); 570 } 571 if (bp != NULL) 572 brelse(bp); 573 #ifdef QUOTA 574 return (blocksreleased); 575 #endif 576 } 577 578 /* 579 * remove any inodes in the inode cache belonging to dev 580 * 581 * There should not be any active ones, return error if any are found 582 * (nb: this is a user error, not a system err) 583 * 584 * Also, count the references to dev by block devices - this really 585 * has nothing to do with the object of the procedure, but as we have 586 * to scan the inode table here anyway, we might as well get the 587 * extra benefit. 588 * 589 * this is called from sumount()/sys3.c when dev is being unmounted 590 */ 591 #ifdef QUOTA 592 iflush(dev, iq) 593 dev_t dev; 594 struct inode *iq; 595 #else 596 iflush(dev) 597 dev_t dev; 598 #endif 599 { 600 register struct inode *ip; 601 register open = 0; 602 603 for (ip = inode; ip < inodeNINODE; ip++) { 604 #ifdef QUOTA 605 if (ip != iq && ip->i_dev == dev) 606 #else 607 if (ip->i_dev == dev) 608 #endif 609 if (ip->i_count) 610 return(-1); 611 else { 612 remque(ip); 613 ip->i_forw = ip; 614 ip->i_back = ip; 615 /* 616 * as i_count == 0, the inode was on the free 617 * list already, just leave it there, it will 618 * fall off the bottom eventually. We could 619 * perhaps move it to the head of the free 620 * list, but as umounts are done so 621 * infrequently, we would gain very little, 622 * while making the code bigger. 623 */ 624 #ifdef QUOTA 625 dqrele(ip->i_dquot); 626 ip->i_dquot = NODQUOT; 627 #endif 628 } 629 else if (ip->i_count && (ip->i_mode&IFMT)==IFBLK && 630 ip->i_rdev == dev) 631 open++; 632 } 633 return (open); 634 } 635 636 /* 637 * Lock an inode. If its already locked, set the WANT bit and sleep. 638 */ 639 ilock(ip) 640 register struct inode *ip; 641 { 642 643 ILOCK(ip); 644 } 645 646 /* 647 * Unlock an inode. If WANT bit is on, wakeup. 648 */ 649 iunlock(ip) 650 register struct inode *ip; 651 { 652 653 IUNLOCK(ip); 654 } 655