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