1 /* lfs_inode.c 4.19 82/07/24 */ 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 #ifdef QUOTA 14 #include "../h/quota.h" 15 #endif 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&ILOCK) != 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 |= ILOCK; 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 = ILOCK; 172 ip->i_count++; 173 ip->i_lastr = 0; 174 bp = bread(dev, fsbtodb(fs, itod(fs, ino)), 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 int badinum = -1; 215 /* 216 * Decrement reference count of 217 * an inode structure. 218 * On the last reference, 219 * write the inode out and if necessary, 220 * truncate and deallocate the file. 221 */ 222 iput(ip) 223 register struct inode *ip; 224 { 225 226 if ((ip->i_flag & ILOCK) == 0) 227 panic("iput"); 228 /* XXX */ 229 if (ip->i_number == badinum && (ip->i_mode&IFMT) == IFCHR && 230 (major(ip->i_dev) != 3 || minor(ip->i_dev) != 2)) 231 panic("/dev/null"); 232 /* XXX */ 233 iunlock(ip); 234 irele(ip); 235 } 236 237 irele(ip) 238 register struct inode *ip; 239 { 240 register int i, x; 241 register struct inode *jp; 242 int mode; 243 244 if (ip->i_count == 1) { 245 ip->i_flag |= ILOCK; 246 if (ip->i_nlink <= 0) { 247 itrunc(ip); 248 mode = ip->i_mode; 249 ip->i_mode = 0; 250 ip->i_rdev = 0; 251 ip->i_flag |= IUPD|ICHG; 252 ifree(ip, ip->i_number, mode); 253 #ifdef QUOTA 254 chkiq(ip->i_dev, ip, ip->i_uid, 0); 255 dqrele(ip->i_dquot); 256 ip->i_dquot = NODQUOT; 257 #endif 258 } 259 IUPDAT(ip, &time, &time, 0); 260 iunlock(ip); 261 ip->i_flag = 0; 262 /* 263 * Put the inode on the end of the free list. 264 * Possibly in some cases it would be better to 265 * put the inode at the head of the free list, 266 * (eg: where i_mode == 0 || i_number == 0) 267 * but I will think about that later .. kre 268 * (i_number is rarely 0 - only after an i/o error in iget, 269 * where i_mode == 0, the inode will probably be wanted 270 * again soon for an ialloc, so possibly we should keep it) 271 */ 272 if (ifreeh) { 273 *ifreet = ip; 274 ip->i_freeb = ifreet; 275 } else { 276 ifreeh = ip; 277 ip->i_freeb = &ifreeh; 278 } 279 ip->i_freef = NULL; 280 ifreet = &ip->i_freef; 281 } 282 ip->i_count--; 283 } 284 285 /* 286 * Check accessed and update flags on 287 * an inode structure. 288 * If any is on, update the inode 289 * with the current time. 290 * If waitfor is given, then must insure 291 * i/o order so wait for write to complete. 292 */ 293 iupdat(ip, ta, tm, waitfor) 294 register struct inode *ip; 295 time_t *ta, *tm; 296 int waitfor; 297 { 298 register struct buf *bp; 299 struct dinode *dp; 300 register struct fs *fp; 301 302 fp = ip->i_fs; 303 if ((ip->i_flag & (IUPD|IACC|ICHG)) != 0) { 304 if (fp->fs_ronly) 305 return; 306 bp = bread(ip->i_dev, fsbtodb(fp, itod(fp, ip->i_number)), 307 fp->fs_bsize); 308 if (bp->b_flags & B_ERROR) { 309 brelse(bp); 310 return; 311 } 312 if (ip->i_flag&IACC) 313 ip->i_atime = *ta; 314 if (ip->i_flag&IUPD) 315 ip->i_mtime = *tm; 316 if (ip->i_flag&ICHG) 317 ip->i_ctime = time; 318 ip->i_flag &= ~(IUPD|IACC|ICHG); 319 dp = bp->b_un.b_dino + itoo(fp, ip->i_number); 320 dp->di_ic = ip->i_ic; 321 if (waitfor) 322 bwrite(bp); 323 else 324 bdwrite(bp); 325 } 326 } 327 328 /* 329 * Free all the disk blocks associated 330 * with the specified inode structure. 331 * The blocks of the file are removed 332 * in reverse order. This FILO 333 * algorithm will tend to maintain 334 * a contiguous free list much longer 335 * than FIFO. 336 */ 337 itrunc(ip) 338 register struct inode *ip; 339 { 340 register i; 341 dev_t dev; 342 daddr_t bn; 343 struct inode itmp; 344 register struct fs *fs; 345 #ifdef QUOTA 346 register long cnt = 0; 347 long tloop(); 348 #endif 349 350 /* 351 * Clean inode on disk before freeing blocks 352 * to insure no duplicates if system crashes. 353 */ 354 itmp = *ip; 355 itmp.i_size = 0; 356 for (i = 0; i < NDADDR; i++) 357 itmp.i_db[i] = 0; 358 for (i = 0; i < NIADDR; i++) 359 itmp.i_ib[i] = 0; 360 itmp.i_flag |= ICHG|IUPD; 361 iupdat(&itmp, &time, &time, 1); 362 ip->i_flag &= ~(IUPD|IACC|ICHG); 363 364 /* 365 * Only plain files, directories and symbolic 366 * links contain blocks. 367 */ 368 i = ip->i_mode & IFMT; 369 if (i != IFREG && i != IFDIR && i != IFLNK) 370 return; 371 /* 372 * Now return blocks to free list... if machine 373 * crashes, they will be harmless MISSING blocks. 374 */ 375 dev = ip->i_dev; 376 fs = ip->i_fs; 377 /* 378 * release double indirect block first 379 */ 380 bn = ip->i_ib[NIADDR-1]; 381 if (bn != (daddr_t)0) { 382 ip->i_ib[NIADDR - 1] = (daddr_t)0; 383 #ifdef QUOTA 384 cnt += 385 #endif 386 tloop(ip, bn, 1); 387 } 388 /* 389 * release single indirect blocks second 390 */ 391 for (i = NIADDR - 2; i >= 0; i--) { 392 bn = ip->i_ib[i]; 393 if (bn != (daddr_t)0) { 394 ip->i_ib[i] = (daddr_t)0; 395 #ifdef QUOTA 396 cnt += 397 #endif 398 tloop(ip, bn, 0); 399 } 400 } 401 /* 402 * finally release direct blocks 403 */ 404 for (i = NDADDR - 1; i>=0; i--) { 405 register size; 406 407 bn = ip->i_db[i]; 408 if (bn == (daddr_t)0) 409 continue; 410 ip->i_db[i] = (daddr_t)0; 411 fre(ip, bn, size = (off_t)blksize(fs, ip, i)); 412 #ifdef QUOTA 413 cnt += size / DEV_BSIZE; 414 #endif 415 } 416 ip->i_size = 0; 417 /* 418 * Inode was written and flags updated above. 419 * No need to modify flags here. 420 */ 421 #ifdef QUOTA 422 (void) chkdq(ip, -cnt, 0); 423 #endif 424 } 425 426 #ifdef QUOTA 427 long 428 #endif 429 tloop(ip, bn, indflg) 430 register struct inode *ip; 431 daddr_t bn; 432 int indflg; 433 { 434 register i; 435 register struct buf *bp; 436 register daddr_t *bap; 437 register struct fs *fs; 438 daddr_t nb; 439 #ifdef QUOTA 440 register long cnt = 0; 441 #endif 442 443 bp = NULL; 444 fs = ip->i_fs; 445 for (i = NINDIR(fs) - 1; i >= 0; i--) { 446 if (bp == NULL) { 447 bp = bread(ip->i_dev, fsbtodb(fs, bn), fs->fs_bsize); 448 if (bp->b_flags & B_ERROR) { 449 brelse(bp); 450 return; 451 } 452 bap = bp->b_un.b_daddr; 453 } 454 nb = bap[i]; 455 if (nb == (daddr_t)0) 456 continue; 457 if (indflg) { 458 #ifdef QUOTA 459 cnt += 460 #endif 461 tloop(ip, nb, 0); 462 } else { 463 fre(ip, nb, fs->fs_bsize); 464 #ifdef QUOTA 465 cnt += fs->fs_bsize / DEV_BSIZE; 466 #endif 467 } 468 } 469 if (bp != NULL) 470 brelse(bp); 471 fre(ip, bn, fs->fs_bsize); 472 #ifdef QUOTA 473 cnt += fs->fs_bsize / DEV_BSIZE; 474 return(cnt); 475 #endif 476 } 477 478 /* 479 * Make a new file. 480 */ 481 struct inode * 482 maknode(mode) 483 int mode; 484 { 485 register struct inode *ip; 486 ino_t ipref; 487 488 if ((mode & IFMT) == IFDIR) 489 ipref = dirpref(u.u_pdir->i_fs); 490 else 491 ipref = u.u_pdir->i_number; 492 ip = ialloc(u.u_pdir, ipref, mode); 493 if (ip == NULL) { 494 iput(u.u_pdir); 495 return(NULL); 496 } 497 #ifdef QUOTA 498 if (ip->i_dquot != NODQUOT) 499 panic("maknode: dquot"); 500 #endif 501 ip->i_flag |= IACC|IUPD|ICHG; 502 if ((mode & IFMT) == 0) 503 mode |= IFREG; 504 ip->i_mode = mode & ~u.u_cmask; 505 ip->i_nlink = 1; 506 ip->i_uid = u.u_uid; 507 ip->i_gid = u.u_pdir->i_gid; 508 #ifdef QUOTA 509 ip->i_dquot = inoquota(ip); 510 #endif 511 512 /* 513 * Make sure inode goes to disk before directory entry. 514 */ 515 iupdat(ip, &time, &time, 1); 516 wdir(ip); 517 if (u.u_error) { 518 /* 519 * write error occurred trying to update directory 520 * so must deallocate the inode 521 */ 522 ip->i_nlink = 0; 523 ip->i_flag |= ICHG; 524 iput(ip); 525 return(NULL); 526 } 527 return(ip); 528 } 529 530 /* 531 * Write a directory entry with 532 * parameters left as side effects 533 * to a call to namei. 534 */ 535 wdir(ip) 536 struct inode *ip; 537 { 538 register struct direct *dp, *ndp; 539 struct fs *fs; 540 struct buf *bp; 541 int lbn, bn, base; 542 int loc, dsize, spccnt, newsize; 543 char *dirbuf; 544 545 u.u_dent.d_ino = ip->i_number; 546 u.u_segflg = 1; 547 newsize = DIRSIZ(&u.u_dent); 548 /* 549 * if u.u_count == 0, a new directory block must be allocated. 550 */ 551 if (u.u_count == 0) { 552 u.u_dent.d_reclen = DIRBLKSIZ; 553 u.u_count = newsize; 554 u.u_base = (caddr_t)&u.u_dent; 555 /*ZZ*/if((u.u_offset&0x1ff))panic("wdir: newblk"); 556 writei(u.u_pdir); 557 iput(u.u_pdir); 558 return; 559 } 560 /* 561 * must read in an existing directory block 562 * to prepare to place the new entry into it. 563 */ 564 fs = u.u_pdir->i_fs; 565 lbn = lblkno(fs, u.u_offset); 566 base = blkoff(fs, u.u_offset); 567 bn = fsbtodb(fs, bmap(u.u_pdir, lbn, B_WRITE, base + u.u_count)); 568 if (u.u_offset + u.u_count > u.u_pdir->i_size) 569 /*ZZ*/{if((u.u_offset+u.u_count-1&~0x1ff)!=(u.u_pdir->i_size-1&~0x1ff)) 570 /*ZZ*/ printf("wdir i_size dir %s/%d (of=%d,cnt=%d,psz=%d))\n", 571 /*ZZ*/ u.u_pdir->i_fs->fs_fsmnt,u.u_pdir->i_number,u.u_offset, 572 /*ZZ*/ u.u_count,u.u_pdir->i_size); 573 u.u_pdir->i_size = u.u_offset + u.u_count; 574 /*ZZ*/} 575 bp = bread(u.u_pdir->i_dev, bn, blksize(fs, u.u_pdir, lbn)); 576 if (bp->b_flags & B_ERROR) { 577 brelse(bp); 578 return; 579 } 580 dirbuf = bp->b_un.b_addr + base; 581 dp = (struct direct *)dirbuf; 582 dsize = DIRSIZ(dp); 583 spccnt = dp->d_reclen - dsize; 584 /* 585 * if there is insufficient room to make an entry at this point 586 * namei insures that compacting from u.u_offset for u.u_count 587 * bytes will provide the necessary space. 588 */ 589 for (loc = dp->d_reclen; loc < u.u_count; ) { 590 ndp = (struct direct *)(dirbuf + loc); 591 if (dp->d_ino == 0) { 592 spccnt += dsize; 593 } else { 594 dp->d_reclen = dsize; 595 dp = (struct direct *)((char *)dp + dsize); 596 } 597 dsize = DIRSIZ(ndp); 598 spccnt += ndp->d_reclen - dsize; 599 /*ZZ*/if(spccnt>512)panic("wdir spccnt"); 600 /*ZZ*/if((loc&~0x1ff)!=(loc+ndp->d_reclen-1&~0x1ff)) 601 /*ZZ*/printf("wdir: compact loc %d reclen %d (dir %s/%d)\n",loc,ndp->d_reclen, 602 /*ZZ*/u.u_pdir->i_fs->fs_fsmnt,u.u_pdir->i_number); 603 loc += ndp->d_reclen; 604 bcopy(ndp, dp, dsize); 605 } 606 /* 607 * Update the pointer fields in the previous entry (if any), 608 * copy in the new entry, and write out the block. 609 */ 610 if (dp->d_ino == 0) { 611 if (spccnt + dsize < newsize) 612 panic("wdir: compact failed (1)"); 613 /*ZZ*/if(spccnt+dsize>512)panic("wdir: compact screwup"); 614 u.u_dent.d_reclen = spccnt + dsize; 615 } else { 616 if (spccnt < newsize) 617 panic("wdir: compact failed (2)"); 618 u.u_dent.d_reclen = spccnt; 619 /*ZZ*/if ((((char *)dp-bp->b_un.b_addr)&0x1ff)+dsize>512) panic("wdir: reclen"); 620 dp->d_reclen = dsize; 621 dp = (struct direct *)((char *)dp + dsize); 622 } 623 /*ZZ*/if((((char*)dp-bp->b_un.b_addr)&0x1ff)+u.u_dent.d_reclen>512)panic("wdir: botch"); 624 bcopy(&u.u_dent, dp, newsize); 625 bwrite(bp); 626 u.u_pdir->i_flag |= IUPD|ICHG; 627 iput(u.u_pdir); 628 } 629 630 /* 631 * remove any inodes in the inode cache belonging to dev 632 * 633 * There should not be any active ones, return error if any are found 634 * (nb: this is a user error, not a system err) 635 * 636 * Also, count the references to dev by block devices - this really 637 * has nothing to do with the object of the procedure, but as we have 638 * to scan the inode table here anyway, we might as well get the 639 * extra benefit. 640 * 641 * this is called from sumount()/sys3.c when dev is being unmounted 642 */ 643 #ifdef QUOTA 644 iflush(dev, iq) 645 dev_t dev; 646 struct inode *iq; 647 #else 648 iflush(dev) 649 dev_t dev; 650 #endif 651 { 652 register struct inode *ip; 653 register open = 0; 654 655 for (ip = inode; ip < inodeNINODE; ip++) { 656 #ifdef QUOTA 657 if (ip != iq && ip->i_dev == dev) 658 #else 659 if (ip->i_dev == dev) 660 #endif 661 if (ip->i_count) 662 return(-1); 663 else { 664 remque(ip); 665 ip->i_forw = ip; 666 ip->i_back = ip; 667 /* 668 * as i_count == 0, the inode was on the free 669 * list already, just leave it there, it will 670 * fall off the bottom eventually. We could 671 * perhaps move it to the head of the free 672 * list, but as umounts are done so 673 * infrequently, we would gain very little, 674 * while making the code bigger. 675 */ 676 #ifdef QUOTA 677 dqrele(ip->i_dquot); 678 ip->i_dquot = NODQUOT; 679 #endif 680 } 681 else if (ip->i_count && (ip->i_mode&IFMT)==IFBLK && 682 ip->i_rdev == dev) 683 open++; 684 } 685 return (open); 686 } 687 688 #ifdef ilock 689 #undef ilock 690 #endif 691 #ifdef iunlock 692 #undef iunlock 693 #endif 694 /* 695 * Lock an inode. If its already locked, set the WANT bit and sleep. 696 */ 697 ilock(ip) 698 register struct inode *ip; 699 { 700 701 while (ip->i_flag&ILOCK) { 702 ip->i_flag |= IWANT; 703 sleep((caddr_t)ip, PINOD); 704 } 705 ip->i_flag |= ILOCK; 706 } 707 708 /* 709 * Unlock an inode. If WANT bit is on, wakeup. 710 */ 711 iunlock(ip) 712 register struct inode *ip; 713 { 714 715 ip->i_flag &= ~ILOCK; 716 if (ip->i_flag&IWANT) { 717 ip->i_flag &= ~IWANT; 718 wakeup((caddr_t)ip); 719 } 720 } 721