1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * @(#)ufs_inode.c 7.10 (Berkeley) 07/16/89 18 */ 19 20 #include "param.h" 21 #include "systm.h" 22 #include "mount.h" 23 #include "user.h" 24 #include "file.h" 25 #include "buf.h" 26 #include "cmap.h" 27 #include "vnode.h" 28 #include "../ufs/inode.h" 29 #include "../ufs/fs.h" 30 #include "../ufs/ufsmount.h" 31 #ifdef QUOTA 32 #include "../ufs/quota.h" 33 #endif 34 #include "kernel.h" 35 #include "malloc.h" 36 37 #define INOHSZ 512 38 #if ((INOHSZ&(INOHSZ-1)) == 0) 39 #define INOHASH(dev,ino) (((dev)+(ino))&(INOHSZ-1)) 40 #else 41 #define INOHASH(dev,ino) (((unsigned)((dev)+(ino)))%INOHSZ) 42 #endif 43 44 #define INSFREE(ip) {\ 45 if (ifreeh) { \ 46 *ifreet = (ip); \ 47 (ip)->i_freeb = ifreet; \ 48 } else { \ 49 ifreeh = (ip); \ 50 (ip)->i_freeb = &ifreeh; \ 51 } \ 52 (ip)->i_freef = NULL; \ 53 ifreet = &(ip)->i_freef; \ 54 } 55 56 union ihead { /* inode LRU cache, Chris Maltby */ 57 union ihead *ih_head[2]; 58 struct inode *ih_chain[2]; 59 } ihead[INOHSZ]; 60 61 struct inode *ifreeh, **ifreet, *bdevlisth; 62 63 /* 64 * Initialize hash links for inodes 65 * and build inode free list. 66 */ 67 ihinit() 68 { 69 register int i; 70 register struct inode *ip = inode; 71 register union ihead *ih = ihead; 72 73 for (i = INOHSZ; --i >= 0; ih++) { 74 ih->ih_head[0] = ih; 75 ih->ih_head[1] = ih; 76 } 77 ifreeh = ip; 78 ifreet = &ip->i_freef; 79 ip->i_freeb = &ifreeh; 80 ip->i_forw = ip; 81 ip->i_back = ip; 82 ITOV(ip)->v_data = (qaddr_t)ip; 83 for (i = ninode; --i > 0; ) { 84 ++ip; 85 ip->i_forw = ip; 86 ip->i_back = ip; 87 ITOV(ip)->v_data = (qaddr_t)ip; 88 *ifreet = ip; 89 ip->i_freeb = ifreet; 90 ifreet = &ip->i_freef; 91 } 92 ip->i_freef = NULL; 93 } 94 95 /* 96 * Look up an vnode/inode by device,inumber. 97 * If it is in core (in the inode structure), 98 * honor the locking protocol. 99 * If it is not in core, read it in from the 100 * specified device. 101 * Callers must check for mount points!! 102 * In all cases, a pointer to a locked 103 * inode structure is returned. 104 */ 105 iget(xp, ino, ipp) 106 struct inode *xp; 107 ino_t ino; 108 struct inode **ipp; 109 { 110 dev_t dev = xp->i_dev; 111 struct mount *mntp = ITOV(xp)->v_mount; 112 register struct fs *fs = VFSTOUFS(mntp)->um_fs; 113 register struct inode *ip, *iq; 114 register struct vnode *vp; 115 struct inode *nip; 116 struct buf *bp; 117 struct dinode tdip, *dp; 118 union ihead *ih; 119 int error; 120 121 loop: 122 ih = &ihead[INOHASH(dev, ino)]; 123 for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw) 124 if (ino == ip->i_number && dev == ip->i_dev) { 125 /* 126 * Following is essentially an inline expanded 127 * copy of igrab(), expanded inline for speed, 128 * and so that the test for a mounted on inode 129 * can be deferred until after we are sure that 130 * the inode isn't busy. 131 */ 132 if ((ip->i_flag&ILOCKED) != 0) { 133 ip->i_flag |= IWANT; 134 sleep((caddr_t)ip, PINOD); 135 goto loop; 136 } 137 vp = ITOV(ip); 138 if (vp->v_count == 0) { /* ino on free list */ 139 if (iq = ip->i_freef) 140 iq->i_freeb = ip->i_freeb; 141 else 142 ifreet = ip->i_freeb; 143 *ip->i_freeb = iq; 144 ip->i_freef = NULL; 145 ip->i_freeb = NULL; 146 } 147 ILOCK(ip); 148 VREF(vp); 149 *ipp = ip; 150 return(0); 151 } 152 if (error = getnewino(dev, ino, &nip)) { 153 *ipp = 0; 154 return (error); 155 } 156 ip = nip; 157 /* 158 * Read in the disk contents for the inode. 159 */ 160 if (error = bread(VFSTOUFS(mntp)->um_devvp, fsbtodb(fs, itod(fs, ino)), 161 (int)fs->fs_bsize, &bp)) { 162 /* 163 * The inode doesn't contain anything useful, so it would 164 * be misleading to leave it on its hash chain. Iput() will 165 * take care of putting it back on the free list. We also 166 * lose its inumber, just in case. 167 */ 168 remque(ip); 169 ip->i_forw = ip; 170 ip->i_back = ip; 171 ip->i_number = 0; 172 INSFREE(ip); 173 iunlock(ip); 174 ip->i_flag = 0; 175 brelse(bp); 176 *ipp = 0; 177 return(error); 178 } 179 /* 180 * Check to see if the new inode represents a block device 181 * for which we already have an inode (either because of 182 * bdevvp() or because of a different inode representing 183 * the same block device). If such an alias exists, put the 184 * just allocated inode back on the free list, and replace 185 * the contents of the existing inode with the contents of 186 * the new inode. 187 */ 188 dp = bp->b_un.b_dino; 189 dp += itoo(fs, ino); 190 if ((dp->di_mode & IFMT) != IFBLK) { 191 ip->i_ic = dp->di_ic; 192 brelse(bp); 193 } else { 194 again: 195 for (iq = bdevlisth; iq; iq = iq->i_devlst) { 196 if (dp->di_rdev != ITOV(iq)->v_rdev) 197 continue; 198 igrab(iq); 199 if (dp->di_rdev != ITOV(iq)->v_rdev) { 200 iput(iq); 201 goto again; 202 } 203 /* 204 * Discard unneeded inode. 205 */ 206 remque(ip); 207 ip->i_forw = ip; 208 ip->i_back = ip; 209 ip->i_number = 0; 210 INSFREE(ip); 211 iunlock(ip); 212 ip->i_flag = 0; 213 /* 214 * Reinitialize aliased inode. 215 * We must release the buffer that we just read 216 * before doing the iupdat() to avoid a possible 217 * deadlock with updating an inode in the same 218 * disk block. 219 */ 220 ip = iq; 221 vp = ITOV(iq); 222 tdip.di_ic = dp->di_ic; 223 brelse(bp); 224 error = iupdat(ip, &time, &time, 1); 225 ip->i_ic = tdip.di_ic; 226 remque(ip); 227 insque(ip, ih); 228 ip->i_dev = dev; 229 ip->i_number = ino; 230 if (ip->i_devvp) { 231 vrele(ip->i_devvp); 232 ip->i_devvp = 0; 233 } 234 cache_purge(vp); 235 break; 236 } 237 if (iq == 0) { 238 ip->i_ic = dp->di_ic; 239 brelse(bp); 240 ip->i_devlst = bdevlisth; 241 bdevlisth = ip; 242 } 243 } 244 /* 245 * Finish inode initialization. 246 */ 247 ip->i_fs = fs; 248 ip->i_devvp = VFSTOUFS(mntp)->um_devvp; 249 VREF(ip->i_devvp); 250 /* 251 * Initialize the associated vnode 252 */ 253 vp = ITOV(ip); 254 vinit(vp, mntp, IFTOVT(ip->i_mode), &ufs_vnodeops); 255 if (vp->v_type == VCHR || vp->v_type == VBLK) { 256 vp->v_rdev = ip->i_rdev; 257 vp->v_op = &blk_vnodeops; 258 } 259 if (ino == ROOTINO) 260 vp->v_flag |= VROOT; 261 #ifdef QUOTA 262 if (ip->i_mode != 0) 263 ip->i_dquot = inoquota(ip); 264 #endif 265 /* 266 * Set up a generation number for this inode if it does not 267 * already have one. This should only happen on old filesystems. 268 */ 269 if (ip->i_gen == 0) { 270 if (++nextgennumber < (u_long)time.tv_sec) 271 nextgennumber = time.tv_sec; 272 ip->i_gen = nextgennumber; 273 if ((vp->v_mount->m_flag & M_RDONLY) == 0) 274 ip->i_flag |= IMOD; 275 } 276 *ipp = ip; 277 return (0); 278 } 279 280 /* 281 * Allocate a new inode. 282 * 283 * Put it onto its hash chain and lock it so that other requests for 284 * this inode will block if they arrive while we are sleeping waiting 285 * for old data structures to be purged or for the contents of the disk 286 * portion of this inode to be read. 287 */ 288 getnewino(dev, ino, ipp) 289 dev_t dev; 290 ino_t ino; 291 struct inode **ipp; 292 { 293 union ihead *ih; 294 register struct inode *ip, *iq; 295 register struct vnode *vp; 296 297 /* 298 * Remove the next inode from the free list. 299 */ 300 if ((ip = ifreeh) == NULL) { 301 tablefull("inode"); 302 *ipp = 0; 303 return(ENFILE); 304 } 305 vp = ITOV(ip); 306 if (vp->v_count) 307 panic("free inode isn't"); 308 if (iq = ip->i_freef) 309 iq->i_freeb = &ifreeh; 310 ifreeh = iq; 311 ip->i_freef = NULL; 312 ip->i_freeb = NULL; 313 /* 314 * Now to take inode off the hash chain it was on 315 * (initially, or after an iflush, it is on a "hash chain" 316 * consisting entirely of itself, and pointed to by no-one) 317 * and put it on the chain for its new (ino, dev) pair. 318 */ 319 remque(ip); 320 ip->i_dev = dev; 321 ip->i_number = ino; 322 if (dev != NODEV) { 323 ih = &ihead[INOHASH(dev, ino)]; 324 insque(ip, ih); 325 } 326 ip->i_flag = 0; 327 ILOCK(ip); 328 ip->i_lastr = 0; 329 /* 330 * Purge old data structures associated with the inode. 331 */ 332 cache_purge(vp); 333 if (ip->i_devvp) { 334 vrele(ip->i_devvp); 335 ip->i_devvp = 0; 336 } 337 #ifdef QUOTA 338 dqrele(ip->i_dquot); 339 ip->i_dquot = NODQUOT; 340 #endif 341 if (vp->v_type == VBLK) { 342 if (bdevlisth == ip) { 343 bdevlisth = ip->i_devlst; 344 } else { 345 for (iq = bdevlisth; iq; iq = iq->i_devlst) { 346 if (iq->i_devlst != ip) 347 continue; 348 iq->i_devlst = ip->i_devlst; 349 break; 350 } 351 if (iq == NULL) 352 panic("missing bdev"); 353 } 354 } 355 *ipp = ip; 356 return (0); 357 } 358 359 /* 360 * Convert a pointer to an inode into a reference to an inode. 361 * 362 * This is basically the internal piece of iget (after the 363 * inode pointer is located) but without the test for mounted 364 * filesystems. It is caller's responsibility to check that 365 * the inode pointer is valid. 366 */ 367 igrab(ip) 368 register struct inode *ip; 369 { 370 register struct vnode *vp = ITOV(ip); 371 372 while ((ip->i_flag&ILOCKED) != 0) { 373 ip->i_flag |= IWANT; 374 sleep((caddr_t)ip, PINOD); 375 } 376 if (vp->v_count == 0) { /* ino on free list */ 377 register struct inode *iq; 378 379 if (iq = ip->i_freef) 380 iq->i_freeb = ip->i_freeb; 381 else 382 ifreet = ip->i_freeb; 383 *ip->i_freeb = iq; 384 ip->i_freef = NULL; 385 ip->i_freeb = NULL; 386 } 387 VREF(vp); 388 ILOCK(ip); 389 } 390 391 /* 392 * Create a vnode for a block device. 393 * Used for root filesystem, argdev, and swap areas. 394 */ 395 bdevvp(dev, vpp) 396 dev_t dev; 397 struct vnode **vpp; 398 { 399 register struct inode *ip; 400 register struct vnode *vp; 401 struct inode *nip; 402 int error; 403 404 /* 405 * Check for the existence of an existing vnode. 406 */ 407 again: 408 for (ip = bdevlisth; ip; ip = ip->i_devlst) { 409 vp = ITOV(ip); 410 if (dev != vp->v_rdev) 411 continue; 412 igrab(ip); 413 if (dev != vp->v_rdev) { 414 iput(ip); 415 goto again; 416 } 417 IUNLOCK(ip); 418 *vpp = vp; 419 return (0); 420 } 421 if (error = getnewino(NODEV, (ino_t)0, &nip)) { 422 *vpp = 0; 423 return (error); 424 } 425 ip = nip; 426 ip->i_fs = 0; 427 ip->i_devlst = bdevlisth; 428 bdevlisth = ip; 429 vp = ITOV(ip); 430 vinit(vp, 0, VBLK, &blk_vnodeops); 431 vp->v_rdev = dev; 432 IUNLOCK(ip); 433 *vpp = vp; 434 return (0); 435 } 436 437 /* 438 * Decrement reference count of 439 * an inode structure. 440 * On the last reference, 441 * write the inode out and if necessary, 442 * truncate and deallocate the file. 443 */ 444 iput(ip) 445 register struct inode *ip; 446 { 447 448 if ((ip->i_flag & ILOCKED) == 0) 449 panic("iput"); 450 IUNLOCK(ip); 451 vrele(ITOV(ip)); 452 } 453 454 455 ufs_inactive(vp) 456 struct vnode *vp; 457 { 458 register struct inode *ip = VTOI(vp); 459 int mode, error; 460 461 if (ITOV(ip)->v_count != 0) 462 panic("ufs_inactive: not inactive"); 463 /* 464 * Get rid of inodes related to stale file handles. 465 */ 466 if (ip->i_mode == 0) 467 goto freeit; 468 ILOCK(ip); 469 if (ip->i_nlink <= 0 && (ITOV(ip)->v_mount->m_flag&M_RDONLY) == 0) { 470 error = itrunc(ip, (u_long)0); 471 mode = ip->i_mode; 472 ip->i_mode = 0; 473 ip->i_rdev = 0; 474 ip->i_flag |= IUPD|ICHG; 475 ifree(ip, ip->i_number, mode); 476 #ifdef QUOTA 477 (void) chkiq(ip->i_dev, ip, ip->i_uid, 0); 478 dqrele(ip->i_dquot); 479 ip->i_dquot = NODQUOT; 480 #endif 481 } 482 IUPDAT(ip, &time, &time, 0); 483 IUNLOCK(ip); 484 freeit: 485 ip->i_flag = 0; 486 /* 487 * Put the inode on the end of the free list. 488 * Possibly in some cases it would be better to 489 * put the inode at the head of the free list, 490 * (eg: where i_mode == 0 || i_number == 0). 491 */ 492 INSFREE(ip); 493 return (error); 494 } 495 496 /* 497 * Check accessed and update flags on 498 * an inode structure. 499 * If any is on, update the inode 500 * with the current time. 501 * If waitfor is given, then must insure 502 * i/o order so wait for write to complete. 503 */ 504 iupdat(ip, ta, tm, waitfor) 505 register struct inode *ip; 506 struct timeval *ta, *tm; 507 int waitfor; 508 { 509 struct buf *bp; 510 struct vnode *vp = ITOV(ip); 511 struct dinode *dp; 512 register struct fs *fs; 513 int error; 514 515 fs = ip->i_fs; 516 if ((ip->i_flag & (IUPD|IACC|ICHG|IMOD)) == 0) 517 return (0); 518 if (vp->v_mount->m_flag & M_RDONLY) 519 return (0); 520 error = bread(ip->i_devvp, fsbtodb(fs, itod(fs, ip->i_number)), 521 (int)fs->fs_bsize, &bp); 522 if (error) { 523 brelse(bp); 524 return (error); 525 } 526 if (ip->i_flag&IACC) 527 ip->i_atime = ta->tv_sec; 528 if (ip->i_flag&IUPD) 529 ip->i_mtime = tm->tv_sec; 530 if (ip->i_flag&ICHG) 531 ip->i_ctime = time.tv_sec; 532 ip->i_flag &= ~(IUPD|IACC|ICHG|IMOD); 533 dp = bp->b_un.b_dino + itoo(fs, ip->i_number); 534 dp->di_ic = ip->i_ic; 535 if (waitfor) { 536 return (bwrite(bp)); 537 } else { 538 bdwrite(bp); 539 return (0); 540 } 541 } 542 543 #define SINGLE 0 /* index of single indirect block */ 544 #define DOUBLE 1 /* index of double indirect block */ 545 #define TRIPLE 2 /* index of triple indirect block */ 546 /* 547 * Truncate the inode ip to at most 548 * length size. Free affected disk 549 * blocks -- the blocks of the file 550 * are removed in reverse order. 551 * 552 * NB: triple indirect blocks are untested. 553 */ 554 itrunc(oip, length) 555 register struct inode *oip; 556 u_long length; 557 { 558 register daddr_t lastblock; 559 daddr_t bn, lbn, lastiblock[NIADDR]; 560 register struct fs *fs; 561 register struct inode *ip; 562 struct buf *bp; 563 int offset, osize, size, level; 564 long count, nblocks, blocksreleased = 0; 565 register int i; 566 int error, allerror = 0; 567 struct inode tip; 568 569 if (oip->i_size <= length) { 570 oip->i_flag |= ICHG|IUPD; 571 error = iupdat(oip, &time, &time, 1); 572 return (error); 573 } 574 /* 575 * Calculate index into inode's block list of 576 * last direct and indirect blocks (if any) 577 * which we want to keep. Lastblock is -1 when 578 * the file is truncated to 0. 579 */ 580 fs = oip->i_fs; 581 lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1; 582 lastiblock[SINGLE] = lastblock - NDADDR; 583 lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs); 584 lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs); 585 nblocks = btodb(fs->fs_bsize); 586 /* 587 * Update the size of the file. If the file is not being 588 * truncated to a block boundry, the contents of the 589 * partial block following the end of the file must be 590 * zero'ed in case it ever become accessable again because 591 * of subsequent file growth. 592 */ 593 osize = oip->i_size; 594 offset = blkoff(fs, length); 595 if (offset == 0) { 596 oip->i_size = length; 597 } else { 598 lbn = lblkno(fs, length); 599 error = balloc(oip, lbn, offset, &bn, B_CLRBUF); 600 if (error) 601 return (error); 602 if ((long)bn < 0) 603 panic("itrunc: hole"); 604 oip->i_size = length; 605 size = blksize(fs, oip, lbn); 606 count = howmany(size, CLBYTES); 607 for (i = 0; i < count; i++) 608 munhash(oip->i_devvp, bn + i * CLBYTES / DEV_BSIZE); 609 error = bread(oip->i_devvp, bn, size, &bp); 610 if (error) { 611 oip->i_size = osize; 612 brelse(bp); 613 return (error); 614 } 615 bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset)); 616 bdwrite(bp); 617 } 618 /* 619 * Update file and block pointers 620 * on disk before we start freeing blocks. 621 * If we crash before free'ing blocks below, 622 * the blocks will be returned to the free list. 623 * lastiblock values are also normalized to -1 624 * for calls to indirtrunc below. 625 */ 626 tip = *oip; 627 tip.i_size = osize; 628 for (level = TRIPLE; level >= SINGLE; level--) 629 if (lastiblock[level] < 0) { 630 oip->i_ib[level] = 0; 631 lastiblock[level] = -1; 632 } 633 for (i = NDADDR - 1; i > lastblock; i--) 634 oip->i_db[i] = 0; 635 oip->i_flag |= ICHG|IUPD; 636 allerror = syncip(oip); 637 638 /* 639 * Indirect blocks first. 640 */ 641 ip = &tip; 642 for (level = TRIPLE; level >= SINGLE; level--) { 643 bn = ip->i_ib[level]; 644 if (bn != 0) { 645 error = indirtrunc(ip, bn, lastiblock[level], level, 646 &count); 647 if (error) 648 allerror = error; 649 blocksreleased += count; 650 if (lastiblock[level] < 0) { 651 ip->i_ib[level] = 0; 652 blkfree(ip, bn, (off_t)fs->fs_bsize); 653 blocksreleased += nblocks; 654 } 655 } 656 if (lastiblock[level] >= 0) 657 goto done; 658 } 659 660 /* 661 * All whole direct blocks or frags. 662 */ 663 for (i = NDADDR - 1; i > lastblock; i--) { 664 register off_t bsize; 665 666 bn = ip->i_db[i]; 667 if (bn == 0) 668 continue; 669 ip->i_db[i] = 0; 670 bsize = (off_t)blksize(fs, ip, i); 671 blkfree(ip, bn, bsize); 672 blocksreleased += btodb(bsize); 673 } 674 if (lastblock < 0) 675 goto done; 676 677 /* 678 * Finally, look for a change in size of the 679 * last direct block; release any frags. 680 */ 681 bn = ip->i_db[lastblock]; 682 if (bn != 0) { 683 off_t oldspace, newspace; 684 685 /* 686 * Calculate amount of space we're giving 687 * back as old block size minus new block size. 688 */ 689 oldspace = blksize(fs, ip, lastblock); 690 ip->i_size = length; 691 newspace = blksize(fs, ip, lastblock); 692 if (newspace == 0) 693 panic("itrunc: newspace"); 694 if (oldspace - newspace > 0) { 695 /* 696 * Block number of space to be free'd is 697 * the old block # plus the number of frags 698 * required for the storage we're keeping. 699 */ 700 bn += numfrags(fs, newspace); 701 blkfree(ip, bn, oldspace - newspace); 702 blocksreleased += btodb(oldspace - newspace); 703 } 704 } 705 done: 706 /* BEGIN PARANOIA */ 707 for (level = SINGLE; level <= TRIPLE; level++) 708 if (ip->i_ib[level] != oip->i_ib[level]) 709 panic("itrunc1"); 710 for (i = 0; i < NDADDR; i++) 711 if (ip->i_db[i] != oip->i_db[i]) 712 panic("itrunc2"); 713 /* END PARANOIA */ 714 oip->i_blocks -= blocksreleased; 715 if (oip->i_blocks < 0) /* sanity */ 716 oip->i_blocks = 0; 717 oip->i_flag |= ICHG; 718 #ifdef QUOTA 719 (void) chkdq(oip, -blocksreleased, 0); 720 #endif 721 return (allerror); 722 } 723 724 /* 725 * Release blocks associated with the inode ip and 726 * stored in the indirect block bn. Blocks are free'd 727 * in LIFO order up to (but not including) lastbn. If 728 * level is greater than SINGLE, the block is an indirect 729 * block and recursive calls to indirtrunc must be used to 730 * cleanse other indirect blocks. 731 * 732 * NB: triple indirect blocks are untested. 733 */ 734 indirtrunc(ip, bn, lastbn, level, countp) 735 register struct inode *ip; 736 daddr_t bn, lastbn; 737 int level; 738 long *countp; 739 { 740 register int i; 741 struct buf *bp; 742 register struct fs *fs = ip->i_fs; 743 register daddr_t *bap; 744 daddr_t *copy, nb, last; 745 long blkcount, factor; 746 int nblocks, blocksreleased = 0; 747 int error, allerror = 0; 748 749 /* 750 * Calculate index in current block of last 751 * block to be kept. -1 indicates the entire 752 * block so we need not calculate the index. 753 */ 754 factor = 1; 755 for (i = SINGLE; i < level; i++) 756 factor *= NINDIR(fs); 757 last = lastbn; 758 if (lastbn > 0) 759 last /= factor; 760 nblocks = btodb(fs->fs_bsize); 761 /* 762 * Get buffer of block pointers, zero those 763 * entries corresponding to blocks to be free'd, 764 * and update on disk copy first. 765 */ 766 error = bread(ip->i_devvp, fsbtodb(fs, bn), (int)fs->fs_bsize, &bp); 767 if (error) { 768 brelse(bp); 769 *countp = 0; 770 return (error); 771 } 772 bap = bp->b_un.b_daddr; 773 MALLOC(copy, daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK); 774 bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->fs_bsize); 775 bzero((caddr_t)&bap[last + 1], 776 (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t)); 777 error = bwrite(bp); 778 if (error) 779 allerror = error; 780 bap = copy; 781 782 /* 783 * Recursively free totally unused blocks. 784 */ 785 for (i = NINDIR(fs) - 1; i > last; i--) { 786 nb = bap[i]; 787 if (nb == 0) 788 continue; 789 if (level > SINGLE) { 790 error = indirtrunc(ip, nb, (daddr_t)-1, level - 1, 791 &blkcount); 792 if (error) 793 allerror = error; 794 blocksreleased += blkcount; 795 } 796 blkfree(ip, nb, (off_t)fs->fs_bsize); 797 blocksreleased += nblocks; 798 } 799 800 /* 801 * Recursively free last partial block. 802 */ 803 if (level > SINGLE && lastbn >= 0) { 804 last = lastbn % factor; 805 nb = bap[i]; 806 if (nb != 0) { 807 error = indirtrunc(ip, nb, last, level - 1, &blkcount); 808 if (error) 809 allerror = error; 810 blocksreleased += blkcount; 811 } 812 } 813 FREE(copy, M_TEMP); 814 *countp = blocksreleased; 815 return (allerror); 816 } 817 818 /* 819 * Remove any inodes in the inode cache belonging to dev. 820 * 821 * There should not be any active ones, return error if any are found 822 * (nb: this is a user error, not a system err). 823 */ 824 #ifdef QUOTA 825 iflush(dev, iq) 826 dev_t dev; 827 struct inode *iq; 828 #else 829 iflush(dev) 830 dev_t dev; 831 #endif 832 { 833 register struct inode *ip; 834 835 for (ip = inode; ip < inodeNINODE; ip++) { 836 #ifdef QUOTA 837 if (ip != iq && ip->i_dev == dev) 838 #else 839 if (ip->i_dev == dev) 840 #endif 841 if (ITOV(ip)->v_count) 842 return (EBUSY); 843 else { 844 remque(ip); 845 ip->i_forw = ip; 846 ip->i_back = ip; 847 /* 848 * as v_count == 0, the inode was on the free 849 * list already, just leave it there, it will 850 * fall off the bottom eventually. We could 851 * perhaps move it to the head of the free 852 * list, but as umounts are done so 853 * infrequently, we would gain very little, 854 * while making the code bigger. 855 */ 856 #ifdef QUOTA 857 dqrele(ip->i_dquot); 858 ip->i_dquot = NODQUOT; 859 #endif 860 if (ip->i_devvp) { 861 vrele(ip->i_devvp); 862 ip->i_devvp = 0; 863 } 864 } 865 } 866 return (0); 867 } 868 869 /* 870 * Lock an inode. If its already locked, set the WANT bit and sleep. 871 */ 872 ilock(ip) 873 register struct inode *ip; 874 { 875 876 while (ip->i_flag & ILOCKED) { 877 ip->i_flag |= IWANT; 878 (void) sleep((caddr_t)ip, PINOD); 879 } 880 ip->i_flag |= ILOCKED; 881 } 882 883 /* 884 * Unlock an inode. If WANT bit is on, wakeup. 885 */ 886 iunlock(ip) 887 register struct inode *ip; 888 { 889 890 if ((ip->i_flag & ILOCKED) == 0) 891 printf("unlocking unlocked inode %d on dev 0x%x\n", 892 ip->i_number, ip->i_dev); 893 ip->i_flag &= ~ILOCKED; 894 if (ip->i_flag&IWANT) { 895 ip->i_flag &= ~IWANT; 896 wakeup((caddr_t)ip); 897 } 898 } 899 900 /* 901 * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. 902 * The mode is shifted to select the owner/group/other fields. The 903 * super user is granted all permissions. 904 * 905 * NB: Called from vnode op table. It seems this could all be done 906 * using vattr's but... 907 */ 908 iaccess(ip, mode, cred) 909 register struct inode *ip; 910 register int mode; 911 struct ucred *cred; 912 { 913 register gid_t *gp; 914 register struct vnode *vp = ITOV(ip); 915 int i; 916 917 /* 918 * If you're the super-user, 919 * you always get access. 920 */ 921 if (cred->cr_uid == 0) 922 return (0); 923 /* 924 * Access check is based on only one of owner, group, public. 925 * If not owner, then check group. If not a member of the 926 * group, then check public access. 927 */ 928 if (cred->cr_uid != ip->i_uid) { 929 mode >>= 3; 930 gp = cred->cr_groups; 931 for (i = 0; i < cred->cr_ngroups; i++, gp++) 932 if (ip->i_gid == *gp) 933 goto found; 934 mode >>= 3; 935 found: 936 ; 937 } 938 if ((ip->i_mode & mode) != 0) 939 return (0); 940 return (EACCES); 941 } 942