1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)vfs_subr.c 7.64 (Berkeley) 12/19/91 8 */ 9 10 /* 11 * External virtual filesystem routines 12 */ 13 14 #include <sys/param.h> 15 #include <sys/proc.h> 16 #include <sys/mount.h> 17 #include <sys/time.h> 18 #include <sys/vnode.h> 19 #include <sys/specdev.h> 20 #include <sys/namei.h> 21 #include <sys/ucred.h> 22 #include <sys/buf.h> 23 #include <sys/errno.h> 24 #include <sys/malloc.h> 25 26 /* 27 * Remove a mount point from the list of mounted filesystems. 28 * Unmount of the root is illegal. 29 */ 30 void 31 vfs_remove(mp) 32 register struct mount *mp; 33 { 34 35 if (mp == rootfs) 36 panic("vfs_remove: unmounting root"); 37 mp->mnt_prev->mnt_next = mp->mnt_next; 38 mp->mnt_next->mnt_prev = mp->mnt_prev; 39 mp->mnt_vnodecovered->v_mountedhere = (struct mount *)0; 40 vfs_unlock(mp); 41 } 42 43 /* 44 * Lock a filesystem. 45 * Used to prevent access to it while mounting and unmounting. 46 */ 47 vfs_lock(mp) 48 register struct mount *mp; 49 { 50 51 while(mp->mnt_flag & MNT_MLOCK) { 52 mp->mnt_flag |= MNT_MWAIT; 53 sleep((caddr_t)mp, PVFS); 54 } 55 mp->mnt_flag |= MNT_MLOCK; 56 return (0); 57 } 58 59 /* 60 * Unlock a locked filesystem. 61 * Panic if filesystem is not locked. 62 */ 63 void 64 vfs_unlock(mp) 65 register struct mount *mp; 66 { 67 68 if ((mp->mnt_flag & MNT_MLOCK) == 0) 69 panic("vfs_unlock: not locked"); 70 mp->mnt_flag &= ~MNT_MLOCK; 71 if (mp->mnt_flag & MNT_MWAIT) { 72 mp->mnt_flag &= ~MNT_MWAIT; 73 wakeup((caddr_t)mp); 74 } 75 } 76 77 /* 78 * Mark a mount point as busy. 79 * Used to synchronize access and to delay unmounting. 80 */ 81 vfs_busy(mp) 82 register struct mount *mp; 83 { 84 85 while(mp->mnt_flag & MNT_MPBUSY) { 86 mp->mnt_flag |= MNT_MPWANT; 87 sleep((caddr_t)&mp->mnt_flag, PVFS); 88 } 89 if (mp->mnt_flag & MNT_UNMOUNT) 90 return (1); 91 mp->mnt_flag |= MNT_MPBUSY; 92 return (0); 93 } 94 95 /* 96 * Free a busy filesystem. 97 * Panic if filesystem is not busy. 98 */ 99 vfs_unbusy(mp) 100 register struct mount *mp; 101 { 102 103 if ((mp->mnt_flag & MNT_MPBUSY) == 0) 104 panic("vfs_unbusy: not busy"); 105 mp->mnt_flag &= ~MNT_MPBUSY; 106 if (mp->mnt_flag & MNT_MPWANT) { 107 mp->mnt_flag &= ~MNT_MPWANT; 108 wakeup((caddr_t)&mp->mnt_flag); 109 } 110 } 111 112 /* 113 * Lookup a mount point by filesystem identifier. 114 */ 115 struct mount * 116 getvfs(fsid) 117 fsid_t *fsid; 118 { 119 register struct mount *mp; 120 121 mp = rootfs; 122 do { 123 if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] && 124 mp->mnt_stat.f_fsid.val[1] == fsid->val[1]) { 125 return (mp); 126 } 127 mp = mp->mnt_next; 128 } while (mp != rootfs); 129 return ((struct mount *)0); 130 } 131 132 /* 133 * Set vnode attributes to VNOVAL 134 */ 135 void vattr_null(vap) 136 register struct vattr *vap; 137 { 138 139 vap->va_type = VNON; 140 vap->va_size = vap->va_bytes = VNOVAL; 141 #ifdef _NOQUAD 142 vap->va_size_rsv = vap->va_bytes_rsv = VNOVAL; 143 #endif 144 vap->va_mode = vap->va_nlink = vap->va_uid = vap->va_gid = 145 vap->va_fsid = vap->va_fileid = 146 vap->va_blocksize = vap->va_rdev = 147 vap->va_atime.tv_sec = vap->va_atime.tv_usec = 148 vap->va_mtime.tv_sec = vap->va_mtime.tv_usec = 149 vap->va_ctime.tv_sec = vap->va_ctime.tv_usec = 150 vap->va_flags = vap->va_gen = VNOVAL; 151 } 152 153 /* 154 * Routines having to do with the management of the vnode table. 155 */ 156 struct vnode *vfreeh, **vfreet; 157 extern struct vnodeops dead_vnodeops, spec_vnodeops; 158 extern void vclean(); 159 long numvnodes; 160 struct vattr va_null; 161 162 /* 163 * Initialize the vnode structures and initialize each file system type. 164 */ 165 vfsinit() 166 { 167 struct vfsops **vfsp; 168 169 /* 170 * Initialize the vnode name cache 171 */ 172 nchinit(); 173 /* 174 * Initialize each file system type. 175 */ 176 vattr_null(&va_null); 177 for (vfsp = &vfssw[0]; vfsp <= &vfssw[MOUNT_MAXTYPE]; vfsp++) { 178 if (*vfsp == NULL) 179 continue; 180 (*(*vfsp)->vfs_init)(); 181 } 182 } 183 184 /* 185 * Return the next vnode from the free list. 186 */ 187 getnewvnode(tag, mp, vops, vpp) 188 enum vtagtype tag; 189 struct mount *mp; 190 struct vnodeops *vops; 191 struct vnode **vpp; 192 { 193 register struct vnode *vp, *vq; 194 195 if (numvnodes < desiredvnodes) { 196 vp = (struct vnode *)malloc((u_long)sizeof *vp, 197 M_VNODE, M_WAITOK); 198 bzero((char *)vp, sizeof *vp); 199 numvnodes++; 200 } else { 201 if ((vp = vfreeh) == NULL) { 202 tablefull("vnode"); 203 *vpp = 0; 204 return (ENFILE); 205 } 206 if (vp->v_usecount) 207 panic("free vnode isn't"); 208 if (vq = vp->v_freef) 209 vq->v_freeb = &vfreeh; 210 else 211 vfreet = &vfreeh; 212 vfreeh = vq; 213 vp->v_freef = NULL; 214 vp->v_freeb = NULL; 215 if (vp->v_type != VBAD) 216 vgone(vp); 217 if (vp->v_data) 218 panic("cleaned vnode isn't"); 219 vp->v_flag = 0; 220 vp->v_lastr = 0; 221 vp->v_socket = 0; 222 } 223 vp->v_type = VNON; 224 cache_purge(vp); 225 vp->v_tag = tag; 226 vp->v_op = vops; 227 insmntque(vp, mp); 228 VREF(vp); 229 *vpp = vp; 230 return (0); 231 } 232 233 /* 234 * Move a vnode from one mount queue to another. 235 */ 236 insmntque(vp, mp) 237 register struct vnode *vp; 238 register struct mount *mp; 239 { 240 register struct vnode *vq; 241 242 /* 243 * Delete from old mount point vnode list, if on one. 244 */ 245 if (vp->v_mountb) { 246 if (vq = vp->v_mountf) 247 vq->v_mountb = vp->v_mountb; 248 *vp->v_mountb = vq; 249 } 250 /* 251 * Insert into list of vnodes for the new mount point, if available. 252 */ 253 vp->v_mount = mp; 254 if (mp == NULL) { 255 vp->v_mountf = NULL; 256 vp->v_mountb = NULL; 257 return; 258 } 259 if (vq = mp->mnt_mounth) 260 vq->v_mountb = &vp->v_mountf; 261 vp->v_mountf = vq; 262 vp->v_mountb = &mp->mnt_mounth; 263 mp->mnt_mounth = vp; 264 } 265 266 /* 267 * Make sure all write-behind blocks associated 268 * with mount point are flushed out (from sync). 269 */ 270 mntflushbuf(mountp, flags) 271 struct mount *mountp; 272 int flags; 273 { 274 register struct vnode *vp; 275 276 if ((mountp->mnt_flag & MNT_MPBUSY) == 0) 277 panic("mntflushbuf: not busy"); 278 loop: 279 for (vp = mountp->mnt_mounth; vp; vp = vp->v_mountf) { 280 if (VOP_ISLOCKED(vp)) 281 continue; 282 if (vget(vp)) 283 goto loop; 284 vflushbuf(vp, flags); 285 vput(vp); 286 if (vp->v_mount != mountp) 287 goto loop; 288 } 289 } 290 291 /* 292 * Flush all dirty buffers associated with a vnode. 293 */ 294 vflushbuf(vp, flags) 295 register struct vnode *vp; 296 int flags; 297 { 298 register struct buf *bp; 299 struct buf *nbp; 300 int s; 301 302 loop: 303 s = splbio(); 304 for (bp = vp->v_dirtyblkhd; bp; bp = nbp) { 305 nbp = bp->b_blockf; 306 if ((bp->b_flags & B_BUSY)) 307 continue; 308 if ((bp->b_flags & B_DELWRI) == 0) 309 panic("vflushbuf: not dirty"); 310 bremfree(bp); 311 bp->b_flags |= B_BUSY; 312 splx(s); 313 /* 314 * Wait for I/O associated with indirect blocks to complete, 315 * since there is no way to quickly wait for them below. 316 * NB: This is really specific to ufs, but is done here 317 * as it is easier and quicker. 318 */ 319 if (bp->b_vp == vp || (flags & B_SYNC) == 0) 320 (void) bawrite(bp); 321 else 322 (void) bwrite(bp); 323 goto loop; 324 } 325 splx(s); 326 if ((flags & B_SYNC) == 0) 327 return; 328 s = splbio(); 329 while (vp->v_numoutput) { 330 vp->v_flag |= VBWAIT; 331 sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1); 332 } 333 splx(s); 334 if (vp->v_dirtyblkhd) { 335 vprint("vflushbuf: dirty", vp); 336 goto loop; 337 } 338 } 339 340 /* 341 * Update outstanding I/O count and do wakeup if requested. 342 */ 343 vwakeup(bp) 344 register struct buf *bp; 345 { 346 register struct vnode *vp; 347 348 bp->b_dirtyoff = bp->b_dirtyend = 0; 349 if (vp = bp->b_vp) { 350 vp->v_numoutput--; 351 if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) { 352 if (vp->v_numoutput < 0) 353 panic("vwakeup: neg numoutput"); 354 vp->v_flag &= ~VBWAIT; 355 wakeup((caddr_t)&vp->v_numoutput); 356 } 357 } 358 } 359 360 /* 361 * Invalidate in core blocks belonging to closed or umounted filesystem 362 * 363 * Go through the list of vnodes associated with the file system; 364 * for each vnode invalidate any buffers that it holds. Normally 365 * this routine is preceeded by a bflush call, so that on a quiescent 366 * filesystem there will be no dirty buffers when we are done. Binval 367 * returns the count of dirty buffers when it is finished. 368 */ 369 mntinvalbuf(mountp) 370 struct mount *mountp; 371 { 372 register struct vnode *vp; 373 int dirty = 0; 374 375 if ((mountp->mnt_flag & MNT_MPBUSY) == 0) 376 panic("mntinvalbuf: not busy"); 377 loop: 378 for (vp = mountp->mnt_mounth; vp; vp = vp->v_mountf) { 379 if (vget(vp)) 380 goto loop; 381 dirty += vinvalbuf(vp, 1); 382 vput(vp); 383 if (vp->v_mount != mountp) 384 goto loop; 385 } 386 return (dirty); 387 } 388 389 /* 390 * Flush out and invalidate all buffers associated with a vnode. 391 * Called with the underlying object locked. 392 */ 393 vinvalbuf(vp, save) 394 register struct vnode *vp; 395 int save; 396 { 397 register struct buf *bp; 398 struct buf *nbp, *blist; 399 int s, dirty = 0; 400 401 for (;;) { 402 if (blist = vp->v_dirtyblkhd) 403 /* void */; 404 else if (blist = vp->v_cleanblkhd) 405 /* void */; 406 else 407 break; 408 for (bp = blist; bp; bp = nbp) { 409 nbp = bp->b_blockf; 410 s = splbio(); 411 if (bp->b_flags & B_BUSY) { 412 bp->b_flags |= B_WANTED; 413 sleep((caddr_t)bp, PRIBIO + 1); 414 splx(s); 415 break; 416 } 417 bremfree(bp); 418 bp->b_flags |= B_BUSY; 419 splx(s); 420 if (save && (bp->b_flags & B_DELWRI)) { 421 dirty++; 422 (void) VOP_BWRITE(bp); 423 break; 424 } 425 if (bp->b_vp != vp) 426 reassignbuf(bp, bp->b_vp); 427 else 428 bp->b_flags |= B_INVAL; 429 brelse(bp); 430 } 431 } 432 if (vp->v_dirtyblkhd || vp->v_cleanblkhd) 433 panic("vinvalbuf: flush failed"); 434 return (dirty); 435 } 436 437 /* 438 * Associate a buffer with a vnode. 439 */ 440 bgetvp(vp, bp) 441 register struct vnode *vp; 442 register struct buf *bp; 443 { 444 register struct vnode *vq; 445 register struct buf *bq; 446 447 if (bp->b_vp) 448 panic("bgetvp: not free"); 449 VHOLD(vp); 450 bp->b_vp = vp; 451 if (vp->v_type == VBLK || vp->v_type == VCHR) 452 bp->b_dev = vp->v_rdev; 453 else 454 bp->b_dev = NODEV; 455 /* 456 * Insert onto list for new vnode. 457 */ 458 if (bq = vp->v_cleanblkhd) 459 bq->b_blockb = &bp->b_blockf; 460 bp->b_blockf = bq; 461 bp->b_blockb = &vp->v_cleanblkhd; 462 vp->v_cleanblkhd = bp; 463 } 464 465 /* 466 * Disassociate a buffer from a vnode. 467 */ 468 brelvp(bp) 469 register struct buf *bp; 470 { 471 struct buf *bq; 472 struct vnode *vp; 473 474 if (bp->b_vp == (struct vnode *) 0) 475 panic("brelvp: NULL"); 476 /* 477 * Delete from old vnode list, if on one. 478 */ 479 if (bp->b_blockb) { 480 if (bq = bp->b_blockf) 481 bq->b_blockb = bp->b_blockb; 482 *bp->b_blockb = bq; 483 bp->b_blockf = NULL; 484 bp->b_blockb = NULL; 485 } 486 vp = bp->b_vp; 487 bp->b_vp = (struct vnode *) 0; 488 HOLDRELE(vp); 489 } 490 491 /* 492 * Reassign a buffer from one vnode to another. 493 * Used to assign file specific control information 494 * (indirect blocks) to the vnode to which they belong. 495 */ 496 reassignbuf(bp, newvp) 497 register struct buf *bp; 498 register struct vnode *newvp; 499 { 500 register struct buf *bq, **listheadp; 501 502 if (newvp == NULL) 503 panic("reassignbuf: NULL"); 504 /* 505 * Delete from old vnode list, if on one. 506 */ 507 if (bp->b_blockb) { 508 if (bq = bp->b_blockf) 509 bq->b_blockb = bp->b_blockb; 510 *bp->b_blockb = bq; 511 } 512 /* 513 * If dirty, put on list of dirty buffers; 514 * otherwise insert onto list of clean buffers. 515 */ 516 if (bp->b_flags & B_DELWRI) 517 listheadp = &newvp->v_dirtyblkhd; 518 else 519 listheadp = &newvp->v_cleanblkhd; 520 if (bq = *listheadp) 521 bq->b_blockb = &bp->b_blockf; 522 bp->b_blockf = bq; 523 bp->b_blockb = listheadp; 524 *listheadp = bp; 525 } 526 527 /* 528 * Create a vnode for a block device. 529 * Used for root filesystem, argdev, and swap areas. 530 * Also used for memory file system special devices. 531 */ 532 bdevvp(dev, vpp) 533 dev_t dev; 534 struct vnode **vpp; 535 { 536 register struct vnode *vp; 537 struct vnode *nvp; 538 int error; 539 540 if (dev == NODEV) 541 return (0); 542 error = getnewvnode(VT_NON, (struct mount *)0, &spec_vnodeops, &nvp); 543 if (error) { 544 *vpp = 0; 545 return (error); 546 } 547 vp = nvp; 548 vp->v_type = VBLK; 549 if (nvp = checkalias(vp, dev, (struct mount *)0)) { 550 vput(vp); 551 vp = nvp; 552 } 553 *vpp = vp; 554 return (0); 555 } 556 557 /* 558 * Check to see if the new vnode represents a special device 559 * for which we already have a vnode (either because of 560 * bdevvp() or because of a different vnode representing 561 * the same block device). If such an alias exists, deallocate 562 * the existing contents and return the aliased vnode. The 563 * caller is responsible for filling it with its new contents. 564 */ 565 struct vnode * 566 checkalias(nvp, nvp_rdev, mp) 567 register struct vnode *nvp; 568 dev_t nvp_rdev; 569 struct mount *mp; 570 { 571 register struct vnode *vp; 572 struct vnode **vpp; 573 574 if (nvp->v_type != VBLK && nvp->v_type != VCHR) 575 return (NULLVP); 576 577 vpp = &speclisth[SPECHASH(nvp_rdev)]; 578 loop: 579 for (vp = *vpp; vp; vp = vp->v_specnext) { 580 if (nvp_rdev != vp->v_rdev || nvp->v_type != vp->v_type) 581 continue; 582 /* 583 * Alias, but not in use, so flush it out. 584 */ 585 if (vp->v_usecount == 0) { 586 vgone(vp); 587 goto loop; 588 } 589 if (vget(vp)) 590 goto loop; 591 break; 592 } 593 if (vp == NULL || vp->v_tag != VT_NON) { 594 MALLOC(nvp->v_specinfo, struct specinfo *, 595 sizeof(struct specinfo), M_VNODE, M_WAITOK); 596 nvp->v_rdev = nvp_rdev; 597 nvp->v_hashchain = vpp; 598 nvp->v_specnext = *vpp; 599 nvp->v_specflags = 0; 600 *vpp = nvp; 601 if (vp != NULL) { 602 nvp->v_flag |= VALIASED; 603 vp->v_flag |= VALIASED; 604 vput(vp); 605 } 606 return (NULLVP); 607 } 608 VOP_UNLOCK(vp); 609 vclean(vp, 0); 610 vp->v_op = nvp->v_op; 611 vp->v_tag = nvp->v_tag; 612 nvp->v_type = VNON; 613 insmntque(vp, mp); 614 return (vp); 615 } 616 617 /* 618 * Grab a particular vnode from the free list, increment its 619 * reference count and lock it. The vnode lock bit is set the 620 * vnode is being eliminated in vgone. The process is awakened 621 * when the transition is completed, and an error returned to 622 * indicate that the vnode is no longer usable (possibly having 623 * been changed to a new file system type). 624 */ 625 vget(vp) 626 register struct vnode *vp; 627 { 628 register struct vnode *vq; 629 630 if (vp->v_flag & VXLOCK) { 631 vp->v_flag |= VXWANT; 632 sleep((caddr_t)vp, PINOD); 633 return (1); 634 } 635 if (vp->v_usecount == 0) { 636 if (vq = vp->v_freef) 637 vq->v_freeb = vp->v_freeb; 638 else 639 vfreet = vp->v_freeb; 640 *vp->v_freeb = vq; 641 vp->v_freef = NULL; 642 vp->v_freeb = NULL; 643 } 644 VREF(vp); 645 VOP_LOCK(vp); 646 return (0); 647 } 648 649 /* 650 * Vnode reference, just increment the count 651 */ 652 void vref(vp) 653 struct vnode *vp; 654 { 655 656 vp->v_usecount++; 657 } 658 659 /* 660 * vput(), just unlock and vrele() 661 */ 662 void vput(vp) 663 register struct vnode *vp; 664 { 665 VOP_UNLOCK(vp); 666 vrele(vp); 667 } 668 669 /* 670 * Vnode release. 671 * If count drops to zero, call inactive routine and return to freelist. 672 */ 673 void vrele(vp) 674 register struct vnode *vp; 675 { 676 struct proc *p = curproc; /* XXX */ 677 678 #ifdef DIAGNOSTIC 679 if (vp == NULL) 680 panic("vrele: null vp"); 681 #endif 682 vp->v_usecount--; 683 if (vp->v_usecount > 0) 684 return; 685 #ifdef DIAGNOSTIC 686 if (vp->v_usecount != 0 || vp->v_writecount != 0) { 687 vprint("vrele: bad ref count", vp); 688 panic("vrele: ref cnt"); 689 } 690 #endif 691 if (vfreeh == NULLVP) { 692 /* 693 * insert into empty list 694 */ 695 vfreeh = vp; 696 vp->v_freeb = &vfreeh; 697 } else { 698 /* 699 * insert at tail of list 700 */ 701 *vfreet = vp; 702 vp->v_freeb = vfreet; 703 } 704 vp->v_freef = NULL; 705 vfreet = &vp->v_freef; 706 VOP_INACTIVE(vp, p); 707 } 708 709 /* 710 * Page or buffer structure gets a reference. 711 */ 712 vhold(vp) 713 register struct vnode *vp; 714 { 715 716 vp->v_holdcnt++; 717 } 718 719 /* 720 * Page or buffer structure frees a reference. 721 */ 722 holdrele(vp) 723 register struct vnode *vp; 724 { 725 726 if (vp->v_holdcnt <= 0) 727 panic("holdrele: holdcnt"); 728 vp->v_holdcnt--; 729 } 730 731 /* 732 * Remove any vnodes in the vnode table belonging to mount point mp. 733 * 734 * If MNT_NOFORCE is specified, there should not be any active ones, 735 * return error if any are found (nb: this is a user error, not a 736 * system error). If MNT_FORCE is specified, detach any active vnodes 737 * that are found. 738 */ 739 int busyprt = 0; /* patch to print out busy vnodes */ 740 741 vflush(mp, skipvp, flags) 742 struct mount *mp; 743 struct vnode *skipvp; 744 int flags; 745 { 746 register struct vnode *vp, *nvp; 747 int busy = 0; 748 749 if ((mp->mnt_flag & MNT_MPBUSY) == 0) 750 panic("vflush: not busy"); 751 loop: 752 for (vp = mp->mnt_mounth; vp; vp = nvp) { 753 if (vp->v_mount != mp) 754 goto loop; 755 nvp = vp->v_mountf; 756 /* 757 * Skip over a selected vnode. 758 */ 759 if (vp == skipvp) 760 continue; 761 /* 762 * Skip over a vnodes marked VSYSTEM. 763 */ 764 if ((flags & SKIPSYSTEM) && (vp->v_flag & VSYSTEM)) 765 continue; 766 /* 767 * With v_usecount == 0, all we need to do is clear 768 * out the vnode data structures and we are done. 769 */ 770 if (vp->v_usecount == 0) { 771 vgone(vp); 772 continue; 773 } 774 /* 775 * For block or character devices, revert to an 776 * anonymous device. For all other files, just kill them. 777 */ 778 if (flags & FORCECLOSE) { 779 if (vp->v_type != VBLK && vp->v_type != VCHR) { 780 vgone(vp); 781 } else { 782 vclean(vp, 0); 783 vp->v_op = &spec_vnodeops; 784 insmntque(vp, (struct mount *)0); 785 } 786 continue; 787 } 788 if (busyprt) 789 vprint("vflush: busy vnode", vp); 790 busy++; 791 } 792 if (busy) 793 return (EBUSY); 794 return (0); 795 } 796 797 /* 798 * Disassociate the underlying file system from a vnode. 799 */ 800 void vclean(vp, flags) 801 register struct vnode *vp; 802 int flags; 803 { 804 struct vnodeops *origops; 805 int active; 806 struct proc *p = curproc; /* XXX */ 807 808 /* 809 * Check to see if the vnode is in use. 810 * If so we have to reference it before we clean it out 811 * so that its count cannot fall to zero and generate a 812 * race against ourselves to recycle it. 813 */ 814 if (active = vp->v_usecount) 815 VREF(vp); 816 /* 817 * Prevent the vnode from being recycled or 818 * brought into use while we clean it out. 819 */ 820 if (vp->v_flag & VXLOCK) 821 panic("vclean: deadlock"); 822 vp->v_flag |= VXLOCK; 823 /* 824 * Even if the count is zero, the VOP_INACTIVE routine may still 825 * have the object locked while it cleans it out. The VOP_LOCK 826 * ensures that the VOP_INACTIVE routine is done with its work. 827 * For active vnodes, it ensures that no other activity can 828 * occur while the buffer list is being cleaned out. 829 */ 830 VOP_LOCK(vp); 831 if (flags & DOCLOSE) 832 vinvalbuf(vp, 1); 833 /* 834 * Prevent any further operations on the vnode from 835 * being passed through to the old file system. 836 */ 837 origops = vp->v_op; 838 vp->v_op = &dead_vnodeops; 839 vp->v_tag = VT_NON; 840 /* 841 * If purging an active vnode, it must be unlocked, closed, 842 * and deactivated before being reclaimed. 843 */ 844 (*(origops->vop_unlock))(vp); 845 if (active) { 846 if (flags & DOCLOSE) 847 (*(origops->vop_close))(vp, IO_NDELAY, NOCRED, p); 848 (*(origops->vop_inactive))(vp, p); 849 } 850 /* 851 * Reclaim the vnode. 852 */ 853 if ((*(origops->vop_reclaim))(vp)) 854 panic("vclean: cannot reclaim"); 855 if (active) 856 vrele(vp); 857 /* 858 * Done with purge, notify sleepers in vget of the grim news. 859 */ 860 vp->v_flag &= ~VXLOCK; 861 if (vp->v_flag & VXWANT) { 862 vp->v_flag &= ~VXWANT; 863 wakeup((caddr_t)vp); 864 } 865 } 866 867 /* 868 * Eliminate all activity associated with the requested vnode 869 * and with all vnodes aliased to the requested vnode. 870 */ 871 void vgoneall(vp) 872 register struct vnode *vp; 873 { 874 register struct vnode *vq; 875 876 if (vp->v_flag & VALIASED) { 877 /* 878 * If a vgone (or vclean) is already in progress, 879 * wait until it is done and return. 880 */ 881 if (vp->v_flag & VXLOCK) { 882 vp->v_flag |= VXWANT; 883 sleep((caddr_t)vp, PINOD); 884 return; 885 } 886 /* 887 * Ensure that vp will not be vgone'd while we 888 * are eliminating its aliases. 889 */ 890 vp->v_flag |= VXLOCK; 891 while (vp->v_flag & VALIASED) { 892 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 893 if (vq->v_rdev != vp->v_rdev || 894 vq->v_type != vp->v_type || vp == vq) 895 continue; 896 vgone(vq); 897 break; 898 } 899 } 900 /* 901 * Remove the lock so that vgone below will 902 * really eliminate the vnode after which time 903 * vgone will awaken any sleepers. 904 */ 905 vp->v_flag &= ~VXLOCK; 906 } 907 vgone(vp); 908 } 909 910 /* 911 * Eliminate all activity associated with a vnode 912 * in preparation for reuse. 913 */ 914 void vgone(vp) 915 register struct vnode *vp; 916 { 917 register struct vnode *vq; 918 struct vnode *vx; 919 long count; 920 921 /* 922 * If a vgone (or vclean) is already in progress, 923 * wait until it is done and return. 924 */ 925 if (vp->v_flag & VXLOCK) { 926 vp->v_flag |= VXWANT; 927 sleep((caddr_t)vp, PINOD); 928 return; 929 } 930 /* 931 * Clean out the filesystem specific data. 932 */ 933 vclean(vp, DOCLOSE); 934 /* 935 * Delete from old mount point vnode list, if on one. 936 */ 937 if (vp->v_mountb) { 938 if (vq = vp->v_mountf) 939 vq->v_mountb = vp->v_mountb; 940 *vp->v_mountb = vq; 941 vp->v_mountf = NULL; 942 vp->v_mountb = NULL; 943 } 944 /* 945 * If special device, remove it from special device alias list. 946 */ 947 if (vp->v_type == VBLK || vp->v_type == VCHR) { 948 if (*vp->v_hashchain == vp) { 949 *vp->v_hashchain = vp->v_specnext; 950 } else { 951 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 952 if (vq->v_specnext != vp) 953 continue; 954 vq->v_specnext = vp->v_specnext; 955 break; 956 } 957 if (vq == NULL) 958 panic("missing bdev"); 959 } 960 if (vp->v_flag & VALIASED) { 961 count = 0; 962 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 963 if (vq->v_rdev != vp->v_rdev || 964 vq->v_type != vp->v_type) 965 continue; 966 count++; 967 vx = vq; 968 } 969 if (count == 0) 970 panic("missing alias"); 971 if (count == 1) 972 vx->v_flag &= ~VALIASED; 973 vp->v_flag &= ~VALIASED; 974 } 975 FREE(vp->v_specinfo, M_VNODE); 976 vp->v_specinfo = NULL; 977 } 978 /* 979 * If it is on the freelist, move it to the head of the list. 980 */ 981 if (vp->v_freeb) { 982 if (vq = vp->v_freef) 983 vq->v_freeb = vp->v_freeb; 984 else 985 vfreet = vp->v_freeb; 986 *vp->v_freeb = vq; 987 vp->v_freef = vfreeh; 988 vp->v_freeb = &vfreeh; 989 vfreeh->v_freeb = &vp->v_freef; 990 vfreeh = vp; 991 } 992 vp->v_type = VBAD; 993 } 994 995 /* 996 * Lookup a vnode by device number. 997 */ 998 vfinddev(dev, type, vpp) 999 dev_t dev; 1000 enum vtype type; 1001 struct vnode **vpp; 1002 { 1003 register struct vnode *vp; 1004 1005 for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) { 1006 if (dev != vp->v_rdev || type != vp->v_type) 1007 continue; 1008 *vpp = vp; 1009 return (0); 1010 } 1011 return (1); 1012 } 1013 1014 /* 1015 * Calculate the total number of references to a special device. 1016 */ 1017 vcount(vp) 1018 register struct vnode *vp; 1019 { 1020 register struct vnode *vq; 1021 int count; 1022 1023 if ((vp->v_flag & VALIASED) == 0) 1024 return (vp->v_usecount); 1025 loop: 1026 for (count = 0, vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 1027 if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type) 1028 continue; 1029 /* 1030 * Alias, but not in use, so flush it out. 1031 */ 1032 if (vq->v_usecount == 0) { 1033 vgone(vq); 1034 goto loop; 1035 } 1036 count += vq->v_usecount; 1037 } 1038 return (count); 1039 } 1040 1041 /* 1042 * Print out a description of a vnode. 1043 */ 1044 static char *typename[] = 1045 { "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" }; 1046 1047 vprint(label, vp) 1048 char *label; 1049 register struct vnode *vp; 1050 { 1051 char buf[64]; 1052 1053 if (label != NULL) 1054 printf("%s: ", label); 1055 printf("type %s, usecount %d, writecount %d, refcount %d,", 1056 typename[vp->v_type], vp->v_usecount, vp->v_writecount, 1057 vp->v_holdcnt); 1058 buf[0] = '\0'; 1059 if (vp->v_flag & VROOT) 1060 strcat(buf, "|VROOT"); 1061 if (vp->v_flag & VTEXT) 1062 strcat(buf, "|VTEXT"); 1063 if (vp->v_flag & VSYSTEM) 1064 strcat(buf, "|VSYSTEM"); 1065 if (vp->v_flag & VXLOCK) 1066 strcat(buf, "|VXLOCK"); 1067 if (vp->v_flag & VXWANT) 1068 strcat(buf, "|VXWANT"); 1069 if (vp->v_flag & VBWAIT) 1070 strcat(buf, "|VBWAIT"); 1071 if (vp->v_flag & VALIASED) 1072 strcat(buf, "|VALIASED"); 1073 if (buf[0] != '\0') 1074 printf(" flags (%s)", &buf[1]); 1075 printf("\n\t"); 1076 VOP_PRINT(vp); 1077 } 1078 1079 #ifdef DEBUG 1080 /* 1081 * List all of the locked vnodes in the system. 1082 * Called when debugging the kernel. 1083 */ 1084 printlockedvnodes() 1085 { 1086 register struct mount *mp; 1087 register struct vnode *vp; 1088 1089 printf("Locked vnodes\n"); 1090 mp = rootfs; 1091 do { 1092 for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) 1093 if (VOP_ISLOCKED(vp)) 1094 vprint((char *)0, vp); 1095 mp = mp->mnt_next; 1096 } while (mp != rootfs); 1097 } 1098 #endif 1099 1100 int kinfo_vdebug = 1; 1101 int kinfo_vgetfailed; 1102 #define KINFO_VNODESLOP 10 1103 /* 1104 * Dump vnode list (via kinfo). 1105 * Copyout address of vnode followed by vnode. 1106 */ 1107 /* ARGSUSED */ 1108 kinfo_vnode(op, where, acopysize, arg, aneeded) 1109 int op; 1110 char *where; 1111 int *acopysize, arg, *aneeded; 1112 { 1113 register struct mount *mp = rootfs; 1114 struct mount *omp; 1115 struct vnode *vp; 1116 register char *bp = where, *savebp; 1117 char *ewhere = where + *acopysize; 1118 int error; 1119 1120 #define VPTRSZ sizeof (struct vnode *) 1121 #define VNODESZ sizeof (struct vnode) 1122 if (where == NULL) { 1123 *aneeded = (numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ); 1124 return (0); 1125 } 1126 1127 do { 1128 if (vfs_busy(mp)) { 1129 mp = mp->mnt_next; 1130 continue; 1131 } 1132 savebp = bp; 1133 again: 1134 for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) { 1135 /* 1136 * Check that the vp is still associated with 1137 * this filesystem. RACE: could have been 1138 * recycled onto the same filesystem. 1139 */ 1140 if (vp->v_mount != mp) { 1141 if (kinfo_vdebug) 1142 printf("kinfo: vp changed\n"); 1143 bp = savebp; 1144 goto again; 1145 } 1146 if ((bp + VPTRSZ + VNODESZ <= ewhere) && 1147 ((error = copyout((caddr_t)&vp, bp, VPTRSZ)) || 1148 (error = copyout((caddr_t)vp, bp + VPTRSZ, 1149 VNODESZ)))) 1150 return (error); 1151 bp += VPTRSZ + VNODESZ; 1152 } 1153 omp = mp; 1154 mp = mp->mnt_next; 1155 vfs_unbusy(omp); 1156 } while (mp != rootfs); 1157 1158 *aneeded = bp - where; 1159 if (bp > ewhere) 1160 *acopysize = ewhere - where; 1161 else 1162 *acopysize = bp - where; 1163 return (0); 1164 } 1165