1 /* lfs_inode.c 4.15 82/07/01 */ 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 ip->i_dev = dev; 163 ip->i_fs = fs; 164 ip->i_number = ino; 165 ip->i_flag = ILOCK; 166 ip->i_count++; 167 ip->i_lastr = 0; 168 bp = bread(dev, fsbtodb(fs, itod(fs, ino)), fs->fs_bsize); 169 /* 170 * Check I/O errors 171 */ 172 if ((bp->b_flags&B_ERROR) != 0) { 173 brelse(bp); 174 /* 175 * the inode doesn't contain anything useful, so it would 176 * be misleading to leave it on its hash chain. 177 * 'iput' will take care of putting it back on the free list. 178 */ 179 remque(ip); 180 ip->i_forw = ip; 181 ip->i_back = ip; 182 /* 183 * we also loose its inumber, just in case (as iput 184 * doesn't do that any more) - but as it isn't on its 185 * hash chain, I doubt if this is really necessary .. kre 186 * (probably the two methods are interchangable) 187 */ 188 ip->i_number = 0; 189 iput(ip); 190 return(NULL); 191 } 192 dp = bp->b_un.b_dino; 193 dp += itoo(fs, ino); 194 ip->i_ic = dp->di_ic; 195 brelse(bp); 196 return (ip); 197 } 198 199 /* 200 * Decrement reference count of 201 * an inode structure. 202 * On the last reference, 203 * write the inode out and if necessary, 204 * truncate and deallocate the file. 205 */ 206 iput(ip) 207 register struct inode *ip; 208 { 209 210 if ((ip->i_flag & ILOCK) == 0) 211 panic("iput"); 212 iunlock(ip); 213 irele(ip); 214 } 215 216 irele(ip) 217 register struct inode *ip; 218 { 219 register int i, x; 220 register struct inode *jp; 221 int mode; 222 223 if (ip->i_count == 1) { 224 ip->i_flag |= ILOCK; 225 if (ip->i_nlink <= 0) { 226 itrunc(ip); 227 mode = ip->i_mode; 228 ip->i_mode = 0; 229 ip->i_flag |= IUPD|ICHG; 230 ifree(ip, ip->i_number, mode); 231 } 232 IUPDAT(ip, &time, &time, 0); 233 iunlock(ip); 234 ip->i_flag = 0; 235 /* 236 * Put the inode on the end of the free list. 237 * Possibly in some cases it would be better to 238 * put the inode at the head of the free list, 239 * (eg: where i_mode == 0 || i_number == 0) 240 * but I will think about that later .. kre 241 * (i_number is rarely 0 - only after an i/o error in iget, 242 * where i_mode == 0, the inode will probably be wanted 243 * again soon for an ialloc, so possibly we should keep it) 244 */ 245 if (ifreeh) { 246 *ifreet = ip; 247 ip->i_freeb = ifreet; 248 } else { 249 ifreeh = ip; 250 ip->i_freeb = &ifreeh; 251 } 252 ip->i_freef = NULL; 253 ifreet = &ip->i_freef; 254 } 255 ip->i_count--; 256 } 257 258 /* 259 * Check accessed and update flags on 260 * an inode structure. 261 * If any is on, update the inode 262 * with the current time. 263 * If waitfor is given, then must insure 264 * i/o order so wait for write to complete. 265 */ 266 iupdat(ip, ta, tm, waitfor) 267 register struct inode *ip; 268 time_t *ta, *tm; 269 int waitfor; 270 { 271 register struct buf *bp; 272 struct dinode *dp; 273 register struct fs *fp; 274 275 fp = ip->i_fs; 276 if ((ip->i_flag & (IUPD|IACC|ICHG)) != 0) { 277 if (fp->fs_ronly) 278 return; 279 bp = bread(ip->i_dev, fsbtodb(fp, itod(fp, ip->i_number)), 280 fp->fs_bsize); 281 if (bp->b_flags & B_ERROR) { 282 brelse(bp); 283 return; 284 } 285 if (ip->i_flag&IACC) 286 ip->i_atime = *ta; 287 if (ip->i_flag&IUPD) 288 ip->i_mtime = *tm; 289 if (ip->i_flag&ICHG) 290 ip->i_ctime = time; 291 ip->i_flag &= ~(IUPD|IACC|ICHG); 292 if (waitfor) 293 bwrite(bp); 294 else 295 bdwrite(bp); 296 } 297 } 298 299 /* 300 * Free all the disk blocks associated 301 * with the specified inode structure. 302 * The blocks of the file are removed 303 * in reverse order. This FILO 304 * algorithm will tend to maintain 305 * a contiguous free list much longer 306 * than FIFO. 307 */ 308 itrunc(ip) 309 register struct inode *ip; 310 { 311 register i; 312 dev_t dev; 313 daddr_t bn; 314 struct inode itmp; 315 register struct fs *fs; 316 317 /* 318 * Clean inode on disk before freeing blocks 319 * to insure no duplicates if system crashes. 320 */ 321 itmp = *ip; 322 itmp.i_size = 0; 323 for (i = 0; i < NDADDR; i++) 324 itmp.i_db[i] = 0; 325 for (i = 0; i < NIADDR; i++) 326 itmp.i_ib[i] = 0; 327 itmp.i_flag |= ICHG|IUPD; 328 iupdat(&itmp, &time, &time, 1); 329 ip->i_flag &= ~(IUPD|IACC|ICHG); 330 331 /* 332 * Only plain files, directories and symbolic 333 * links contain blocks. 334 */ 335 i = ip->i_mode & IFMT; 336 if (i != IFREG && i != IFDIR && i != IFLNK) 337 return; 338 /* 339 * Now return blocks to free list... if machine 340 * crashes, they will be harmless MISSING blocks. 341 */ 342 dev = ip->i_dev; 343 fs = ip->i_fs; 344 /* 345 * release double indirect block first 346 */ 347 bn = ip->i_ib[NIADDR-1]; 348 if (bn != (daddr_t)0) { 349 ip->i_ib[NIADDR - 1] = (daddr_t)0; 350 tloop(ip, bn, 1); 351 } 352 /* 353 * release single indirect blocks second 354 */ 355 for (i = NIADDR - 2; i >= 0; i--) { 356 bn = ip->i_ib[i]; 357 if (bn != (daddr_t)0) { 358 ip->i_ib[i] = (daddr_t)0; 359 tloop(ip, bn, 0); 360 } 361 } 362 /* 363 * finally release direct blocks 364 */ 365 for (i = NDADDR - 1; i>=0; i--) { 366 bn = ip->i_db[i]; 367 if (bn == (daddr_t)0) 368 continue; 369 ip->i_db[i] = (daddr_t)0; 370 fre(ip, bn, (off_t)blksize(fs, ip, i)); 371 } 372 ip->i_size = 0; 373 /* 374 * Inode was written and flags updated above. 375 * No need to modify flags here. 376 */ 377 } 378 379 tloop(ip, bn, indflg) 380 register struct inode *ip; 381 daddr_t bn; 382 int indflg; 383 { 384 register i; 385 register struct buf *bp; 386 register daddr_t *bap; 387 register struct fs *fs; 388 daddr_t nb; 389 390 bp = NULL; 391 fs = ip->i_fs; 392 for (i = NINDIR(fs) - 1; i >= 0; i--) { 393 if (bp == NULL) { 394 bp = bread(ip->i_dev, fsbtodb(fs, bn), fs->fs_bsize); 395 if (bp->b_flags & B_ERROR) { 396 brelse(bp); 397 return; 398 } 399 bap = bp->b_un.b_daddr; 400 } 401 nb = bap[i]; 402 if (nb == (daddr_t)0) 403 continue; 404 if (indflg) 405 tloop(ip, nb, 0); 406 else 407 fre(ip, nb, fs->fs_bsize); 408 } 409 if (bp != NULL) 410 brelse(bp); 411 fre(ip, bn, fs->fs_bsize); 412 } 413 414 /* 415 * Make a new file. 416 */ 417 struct inode * 418 maknode(mode) 419 int mode; 420 { 421 register struct inode *ip; 422 ino_t ipref; 423 424 if ((mode & IFMT) == IFDIR) 425 ipref = dirpref(u.u_pdir->i_fs); 426 else 427 ipref = u.u_pdir->i_number; 428 ip = ialloc(u.u_pdir, ipref, mode); 429 if (ip == NULL) { 430 iput(u.u_pdir); 431 return(NULL); 432 } 433 ip->i_flag |= IACC|IUPD|ICHG; 434 if ((mode & IFMT) == 0) 435 mode |= IFREG; 436 ip->i_mode = mode & ~u.u_cmask; 437 ip->i_nlink = 1; 438 ip->i_uid = u.u_uid; 439 ip->i_gid = u.u_pdir->i_gid; 440 441 /* 442 * Make sure inode goes to disk before directory entry. 443 */ 444 iupdat(ip, &time, &time, 1); 445 wdir(ip); 446 if (u.u_error) { 447 /* 448 * write error occurred trying to update directory 449 * so must deallocate the inode 450 */ 451 ip->i_nlink = 0; 452 ip->i_flag |= ICHG; 453 iput(ip); 454 return(NULL); 455 } 456 return(ip); 457 } 458 459 /* 460 * Write a directory entry with 461 * parameters left as side effects 462 * to a call to namei. 463 */ 464 wdir(ip) 465 struct inode *ip; 466 { 467 register struct direct *dp, *ndp; 468 struct fs *fs; 469 struct buf *bp; 470 int lbn, bn, base; 471 int loc, dsize, spccnt, newsize; 472 char *dirbuf; 473 474 u.u_dent.d_ino = ip->i_number; 475 u.u_segflg = 1; 476 newsize = DIRSIZ(&u.u_dent); 477 /* 478 * if u.u_count == 0, a new directory block must be allocated. 479 */ 480 if (u.u_count == 0) { 481 u.u_dent.d_reclen = DIRBLKSIZ; 482 u.u_count = newsize; 483 u.u_base = (caddr_t)&u.u_dent; 484 writei(u.u_pdir); 485 iput(u.u_pdir); 486 return; 487 } 488 /* 489 * must read in an existing directory block 490 * to prepare to place the new entry into it. 491 */ 492 fs = u.u_pdir->i_fs; 493 lbn = lblkno(fs, u.u_offset); 494 base = blkoff(fs, u.u_offset); 495 bn = fsbtodb(fs, bmap(u.u_pdir, lbn, B_WRITE, base + u.u_count)); 496 if (u.u_offset + u.u_count > u.u_pdir->i_size) 497 u.u_pdir->i_size = u.u_offset + u.u_count; 498 bp = bread(u.u_pdir->i_dev, bn, blksize(fs, u.u_pdir, lbn)); 499 if (bp->b_flags & B_ERROR) { 500 brelse(bp); 501 return; 502 } 503 dirbuf = bp->b_un.b_addr + base; 504 dp = (struct direct *)dirbuf; 505 dsize = DIRSIZ(dp); 506 spccnt = dp->d_reclen - dsize; 507 /* 508 * if there is insufficient room to make an entry at this point 509 * namei insures that compacting from u.u_offset for u.u_count 510 * bytes will provide the necessary space. 511 */ 512 for (loc = dp->d_reclen; loc < u.u_count; ) { 513 ndp = (struct direct *)(dirbuf + loc); 514 if (dp->d_ino == 0) { 515 spccnt += dsize; 516 } else { 517 dp->d_reclen = dsize; 518 dp = (struct direct *)((char *)dp + dsize); 519 } 520 dsize = DIRSIZ(ndp); 521 spccnt += ndp->d_reclen - dsize; 522 loc += ndp->d_reclen; 523 bcopy(ndp, dp, dsize); 524 } 525 /* 526 * Update the pointer fields in the previous entry (if any), 527 * copy in the new entry, and write out the block. 528 */ 529 if (dp->d_ino == 0) { 530 if (spccnt + dsize < newsize) 531 panic("wdir: compact failed"); 532 u.u_dent.d_reclen = spccnt + dsize; 533 } else { 534 if (spccnt < newsize) 535 panic("wdir: compact failed"); 536 u.u_dent.d_reclen = spccnt; 537 dp->d_reclen = dsize; 538 dp = (struct direct *)((char *)dp + dsize); 539 } 540 bcopy(&u.u_dent, dp, newsize); 541 bwrite(bp); 542 u.u_pdir->i_flag |= IUPD|ICHG; 543 iput(u.u_pdir); 544 } 545 546 /* 547 * remove any inodes in the inode cache belonging to dev 548 * 549 * There should not be any active ones, return error if any are found 550 * (nb: this is a user error, not a system err) 551 * 552 * Also, count the references to dev by block devices - this really 553 * has nothing to do with the object of the procedure, but as we have 554 * to scan the inode table here anyway, we might as well get the 555 * extra benefit. 556 * 557 * this is called from sumount()/sys3.c when dev is being unmounted 558 */ 559 iflush(dev) 560 dev_t dev; 561 { 562 register struct inode *ip; 563 register open = 0; 564 565 for (ip = inode; ip < inodeNINODE; ip++) { 566 if (ip->i_dev == dev) 567 if (ip->i_count) 568 return(-1); 569 else { 570 remque(ip); 571 ip->i_forw = ip; 572 ip->i_back = ip; 573 /* 574 * as i_count == 0, the inode was on the free 575 * list already, just leave it there, it will 576 * fall off the bottom eventually. We could 577 * perhaps move it to the head of the free 578 * list, but as umounts are done so 579 * infrequently, we would gain very little, 580 * while making the code bigger. 581 */ 582 } 583 else if (ip->i_count && (ip->i_mode&IFMT)==IFBLK && 584 ip->i_rdev == dev) 585 open++; 586 } 587 return (open); 588 } 589 590 #ifdef ilock 591 #undef ilock 592 #endif 593 #ifdef iunlock 594 #undef iunlock 595 #endif 596 /* 597 * Lock an inode. If its already locked, set the WANT bit and sleep. 598 */ 599 ilock(ip) 600 register struct inode *ip; 601 { 602 603 while (ip->i_flag&ILOCK) { 604 ip->i_flag |= IWANT; 605 sleep((caddr_t)ip, PINOD); 606 } 607 ip->i_flag |= ILOCK; 608 } 609 610 /* 611 * Unlock an inode. If WANT bit is on, wakeup. 612 */ 613 iunlock(ip) 614 register struct inode *ip; 615 { 616 617 ip->i_flag &= ~ILOCK; 618 if (ip->i_flag&IWANT) { 619 ip->i_flag &= ~IWANT; 620 wakeup((caddr_t)ip); 621 } 622 } 623