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