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