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.57 (Berkeley) 05/15/91 8 */ 9 10 /* 11 * External virtual filesystem routines 12 */ 13 14 #include "param.h" 15 #include "proc.h" 16 #include "mount.h" 17 #include "time.h" 18 #include "vnode.h" 19 #include "specdev.h" 20 #include "namei.h" 21 #include "ucred.h" 22 #include "buf.h" 23 #include "errno.h" 24 #include "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_mode = vap->va_nlink = vap->va_uid = vap->va_gid = 141 vap->va_fsid = vap->va_fileid = vap->va_size = 142 vap->va_size_rsv = vap->va_blocksize = vap->va_rdev = 143 vap->va_bytes = vap->va_bytes_rsv = 144 vap->va_atime.tv_sec = vap->va_atime.tv_usec = 145 vap->va_mtime.tv_sec = vap->va_mtime.tv_usec = 146 vap->va_ctime.tv_sec = vap->va_ctime.tv_usec = 147 vap->va_flags = vap->va_gen = VNOVAL; 148 } 149 150 /* 151 * Routines having to do with the management of the vnode table. 152 */ 153 struct vnode *vfreeh, **vfreet; 154 extern struct vnodeops dead_vnodeops, spec_vnodeops; 155 extern void vclean(); 156 long numvnodes; 157 struct vattr va_null; 158 159 /* 160 * Initialize the vnode structures and initialize each file system type. 161 */ 162 vfsinit() 163 { 164 struct vfsops **vfsp; 165 166 /* 167 * Initialize the vnode name cache 168 */ 169 nchinit(); 170 /* 171 * Initialize each file system type. 172 */ 173 vattr_null(&va_null); 174 for (vfsp = &vfssw[0]; vfsp <= &vfssw[MOUNT_MAXTYPE]; vfsp++) { 175 if (*vfsp == NULL) 176 continue; 177 (*(*vfsp)->vfs_init)(); 178 } 179 } 180 181 /* 182 * Return the next vnode from the free list. 183 */ 184 getnewvnode(tag, mp, vops, vpp) 185 enum vtagtype tag; 186 struct mount *mp; 187 struct vnodeops *vops; 188 struct vnode **vpp; 189 { 190 register struct vnode *vp, *vq; 191 192 if (numvnodes < desiredvnodes) { 193 vp = (struct vnode *)malloc((u_long)sizeof *vp, 194 M_VNODE, M_WAITOK); 195 bzero((char *)vp, sizeof *vp); 196 numvnodes++; 197 } else { 198 if ((vp = vfreeh) == NULL) { 199 tablefull("vnode"); 200 *vpp = 0; 201 return (ENFILE); 202 } 203 if (vp->v_usecount) 204 panic("free vnode isn't"); 205 if (vq = vp->v_freef) 206 vq->v_freeb = &vfreeh; 207 else 208 vfreet = &vfreeh; 209 vfreeh = vq; 210 vp->v_freef = NULL; 211 vp->v_freeb = NULL; 212 if (vp->v_type != VBAD) 213 vgone(vp); 214 vp->v_flag = 0; 215 vp->v_lastr = 0; 216 vp->v_socket = 0; 217 } 218 vp->v_type = VNON; 219 cache_purge(vp); 220 vp->v_tag = tag; 221 vp->v_op = vops; 222 insmntque(vp, mp); 223 VREF(vp); 224 *vpp = vp; 225 return (0); 226 } 227 228 /* 229 * Move a vnode from one mount queue to another. 230 */ 231 insmntque(vp, mp) 232 register struct vnode *vp; 233 register struct mount *mp; 234 { 235 struct vnode *vq; 236 237 /* 238 * Delete from old mount point vnode list, if on one. 239 */ 240 if (vp->v_mountb) { 241 if (vq = vp->v_mountf) 242 vq->v_mountb = vp->v_mountb; 243 *vp->v_mountb = vq; 244 } 245 /* 246 * Insert into list of vnodes for the new mount point, if available. 247 */ 248 vp->v_mount = mp; 249 if (mp == NULL) { 250 vp->v_mountf = NULL; 251 vp->v_mountb = NULL; 252 return; 253 } 254 if (mp->mnt_mounth) { 255 vp->v_mountf = mp->mnt_mounth; 256 vp->v_mountb = &mp->mnt_mounth; 257 mp->mnt_mounth->v_mountb = &vp->v_mountf; 258 mp->mnt_mounth = vp; 259 } else { 260 mp->mnt_mounth = vp; 261 vp->v_mountb = &mp->mnt_mounth; 262 vp->v_mountf = NULL; 263 } 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) 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 445 if (bp->b_vp) 446 panic("bgetvp: not free"); 447 VHOLD(vp); 448 bp->b_vp = vp; 449 if (vp->v_type == VBLK || vp->v_type == VCHR) 450 bp->b_dev = vp->v_rdev; 451 else 452 bp->b_dev = NODEV; 453 /* 454 * Insert onto list for new vnode. 455 */ 456 if (vp->v_cleanblkhd) { 457 bp->b_blockf = vp->v_cleanblkhd; 458 bp->b_blockb = &vp->v_cleanblkhd; 459 vp->v_cleanblkhd->b_blockb = &bp->b_blockf; 460 vp->v_cleanblkhd = bp; 461 } else { 462 vp->v_cleanblkhd = bp; 463 bp->b_blockb = &vp->v_cleanblkhd; 464 bp->b_blockf = NULL; 465 } 466 } 467 468 /* 469 * Disassociate a buffer from a vnode. 470 */ 471 brelvp(bp) 472 register struct buf *bp; 473 { 474 struct buf *bq; 475 struct vnode *vp; 476 477 if (bp->b_vp == (struct vnode *) 0) 478 panic("brelvp: NULL"); 479 /* 480 * Delete from old vnode list, if on one. 481 */ 482 if (bp->b_blockb) { 483 if (bq = bp->b_blockf) 484 bq->b_blockb = bp->b_blockb; 485 *bp->b_blockb = bq; 486 bp->b_blockf = NULL; 487 bp->b_blockb = NULL; 488 } 489 vp = bp->b_vp; 490 bp->b_vp = (struct vnode *) 0; 491 HOLDRELE(vp); 492 } 493 494 /* 495 * Reassign a buffer from one vnode to another. 496 * Used to assign file specific control information 497 * (indirect blocks) to the vnode to which they belong. 498 */ 499 reassignbuf(bp, newvp) 500 register struct buf *bp; 501 register struct vnode *newvp; 502 { 503 register struct buf *bq, **listheadp; 504 505 if (newvp == NULL) 506 panic("reassignbuf: NULL"); 507 /* 508 * Delete from old vnode list, if on one. 509 */ 510 if (bp->b_blockb) { 511 if (bq = bp->b_blockf) 512 bq->b_blockb = bp->b_blockb; 513 *bp->b_blockb = bq; 514 } 515 /* 516 * If dirty, put on list of dirty buffers; 517 * otherwise insert onto list of clean buffers. 518 */ 519 if (bp->b_flags & B_DELWRI) 520 listheadp = &newvp->v_dirtyblkhd; 521 else 522 listheadp = &newvp->v_cleanblkhd; 523 if (*listheadp) { 524 bp->b_blockf = *listheadp; 525 bp->b_blockb = listheadp; 526 bp->b_blockf->b_blockb = &bp->b_blockf; 527 *listheadp = bp; 528 } else { 529 *listheadp = bp; 530 bp->b_blockb = listheadp; 531 bp->b_blockf = NULL; 532 } 533 } 534 535 /* 536 * Create a vnode for a block device. 537 * Used for root filesystem, argdev, and swap areas. 538 * Also used for memory file system special devices. 539 */ 540 bdevvp(dev, vpp) 541 dev_t dev; 542 struct vnode **vpp; 543 { 544 register struct vnode *vp; 545 struct vnode *nvp; 546 int error; 547 548 if (dev == NODEV) 549 return (0); 550 error = getnewvnode(VT_NON, (struct mount *)0, &spec_vnodeops, &nvp); 551 if (error) { 552 *vpp = 0; 553 return (error); 554 } 555 vp = nvp; 556 vp->v_type = VBLK; 557 if (nvp = checkalias(vp, dev, (struct mount *)0)) { 558 vput(vp); 559 vp = nvp; 560 } 561 *vpp = vp; 562 return (0); 563 } 564 565 /* 566 * Check to see if the new vnode represents a special device 567 * for which we already have a vnode (either because of 568 * bdevvp() or because of a different vnode representing 569 * the same block device). If such an alias exists, deallocate 570 * the existing contents and return the aliased vnode. The 571 * caller is responsible for filling it with its new contents. 572 */ 573 struct vnode * 574 checkalias(nvp, nvp_rdev, mp) 575 register struct vnode *nvp; 576 dev_t nvp_rdev; 577 struct mount *mp; 578 { 579 register struct vnode *vp; 580 struct vnode **vpp; 581 582 if (nvp->v_type != VBLK && nvp->v_type != VCHR) 583 return (NULLVP); 584 585 vpp = &speclisth[SPECHASH(nvp_rdev)]; 586 loop: 587 for (vp = *vpp; vp; vp = vp->v_specnext) { 588 if (nvp_rdev != vp->v_rdev || nvp->v_type != vp->v_type) 589 continue; 590 /* 591 * Alias, but not in use, so flush it out. 592 */ 593 if (vp->v_usecount == 0) { 594 vgone(vp); 595 goto loop; 596 } 597 if (vget(vp)) 598 goto loop; 599 break; 600 } 601 if (vp == NULL || vp->v_tag != VT_NON) { 602 MALLOC(nvp->v_specinfo, struct specinfo *, 603 sizeof(struct specinfo), M_VNODE, M_WAITOK); 604 nvp->v_rdev = nvp_rdev; 605 nvp->v_hashchain = vpp; 606 nvp->v_specnext = *vpp; 607 nvp->v_specflags = 0; 608 *vpp = nvp; 609 if (vp != NULL) { 610 nvp->v_flag |= VALIASED; 611 vp->v_flag |= VALIASED; 612 vput(vp); 613 } 614 return (NULLVP); 615 } 616 VOP_UNLOCK(vp); 617 vclean(vp, 0); 618 vp->v_op = nvp->v_op; 619 vp->v_tag = nvp->v_tag; 620 nvp->v_type = VNON; 621 insmntque(vp, mp); 622 return (vp); 623 } 624 625 /* 626 * Grab a particular vnode from the free list, increment its 627 * reference count and lock it. The vnode lock bit is set the 628 * vnode is being eliminated in vgone. The process is awakened 629 * when the transition is completed, and an error returned to 630 * indicate that the vnode is no longer usable (possibly having 631 * been changed to a new file system type). 632 */ 633 vget(vp) 634 register struct vnode *vp; 635 { 636 register struct vnode *vq; 637 638 if (vp->v_flag & VXLOCK) { 639 vp->v_flag |= VXWANT; 640 sleep((caddr_t)vp, PINOD); 641 return (1); 642 } 643 if (vp->v_usecount == 0) { 644 if (vq = vp->v_freef) 645 vq->v_freeb = vp->v_freeb; 646 else 647 vfreet = vp->v_freeb; 648 *vp->v_freeb = vq; 649 vp->v_freef = NULL; 650 vp->v_freeb = NULL; 651 } 652 VREF(vp); 653 VOP_LOCK(vp); 654 return (0); 655 } 656 657 /* 658 * Vnode reference, just increment the count 659 */ 660 void vref(vp) 661 struct vnode *vp; 662 { 663 664 vp->v_usecount++; 665 } 666 667 /* 668 * vput(), just unlock and vrele() 669 */ 670 void vput(vp) 671 register struct vnode *vp; 672 { 673 VOP_UNLOCK(vp); 674 vrele(vp); 675 } 676 677 /* 678 * Vnode release. 679 * If count drops to zero, call inactive routine and return to freelist. 680 */ 681 void vrele(vp) 682 register struct vnode *vp; 683 { 684 struct proc *p = curproc; /* XXX */ 685 686 if (vp == NULL) 687 panic("vrele: null vp"); 688 vp->v_usecount--; 689 if (vp->v_usecount < 0) 690 vprint("vrele: bad ref count", vp); 691 if (vp->v_usecount > 0) 692 return; 693 if (vfreeh == NULLVP) { 694 /* 695 * insert into empty list 696 */ 697 vfreeh = vp; 698 vp->v_freeb = &vfreeh; 699 } else { 700 /* 701 * insert at tail of list 702 */ 703 *vfreet = vp; 704 vp->v_freeb = vfreet; 705 } 706 vp->v_freef = NULL; 707 vfreet = &vp->v_freef; 708 VOP_INACTIVE(vp, p); 709 } 710 711 /* 712 * Page or buffer structure gets a reference. 713 */ 714 vhold(vp) 715 register struct vnode *vp; 716 { 717 718 vp->v_holdcnt++; 719 } 720 721 /* 722 * Page or buffer structure frees a reference. 723 */ 724 holdrele(vp) 725 register struct vnode *vp; 726 { 727 728 if (vp->v_holdcnt <= 0) 729 panic("holdrele: holdcnt"); 730 vp->v_holdcnt--; 731 } 732 733 /* 734 * Remove any vnodes in the vnode table belonging to mount point mp. 735 * 736 * If MNT_NOFORCE is specified, there should not be any active ones, 737 * return error if any are found (nb: this is a user error, not a 738 * system error). If MNT_FORCE is specified, detach any active vnodes 739 * that are found. 740 */ 741 int busyprt = 0; /* patch to print out busy vnodes */ 742 743 vflush(mp, skipvp, flags) 744 struct mount *mp; 745 struct vnode *skipvp; 746 int flags; 747 { 748 register struct vnode *vp, *nvp; 749 int busy = 0; 750 751 if ((mp->mnt_flag & MNT_MPBUSY) == 0) 752 panic("vflush: not busy"); 753 loop: 754 for (vp = mp->mnt_mounth; vp; vp = nvp) { 755 if (vp->v_mount != mp) 756 goto loop; 757 nvp = vp->v_mountf; 758 /* 759 * Skip over a selected vnode. 760 */ 761 if (vp == skipvp) 762 continue; 763 /* 764 * Skip over a vnodes marked VSYSTEM. 765 */ 766 if ((flags & SKIPSYSTEM) && (vp->v_flag & VSYSTEM)) 767 continue; 768 /* 769 * With v_usecount == 0, all we need to do is clear 770 * out the vnode data structures and we are done. 771 */ 772 if (vp->v_usecount == 0) { 773 vgone(vp); 774 continue; 775 } 776 /* 777 * For block or character devices, revert to an 778 * anonymous device. For all other files, just kill them. 779 */ 780 if (flags & FORCECLOSE) { 781 if (vp->v_type != VBLK && vp->v_type != VCHR) { 782 vgone(vp); 783 } else { 784 vclean(vp, 0); 785 vp->v_op = &spec_vnodeops; 786 insmntque(vp, (struct mount *)0); 787 } 788 continue; 789 } 790 if (busyprt) 791 vprint("vflush: busy vnode", vp); 792 busy++; 793 } 794 if (busy) 795 return (EBUSY); 796 return (0); 797 } 798 799 /* 800 * Disassociate the underlying file system from a vnode. 801 */ 802 void vclean(vp, flags) 803 register struct vnode *vp; 804 int flags; 805 { 806 struct vnodeops *origops; 807 int active; 808 struct proc *p = curproc; /* XXX */ 809 810 /* 811 * Check to see if the vnode is in use. 812 * If so we have to reference it before we clean it out 813 * so that its count cannot fall to zero and generate a 814 * race against ourselves to recycle it. 815 */ 816 if (active = vp->v_usecount) 817 VREF(vp); 818 /* 819 * Prevent the vnode from being recycled or 820 * brought into use while we clean it out. 821 */ 822 if (vp->v_flag & VXLOCK) 823 panic("vclean: deadlock"); 824 vp->v_flag |= VXLOCK; 825 /* 826 * Even if the count is zero, the VOP_INACTIVE routine may still 827 * have the object locked while it cleans it out. The VOP_LOCK 828 * ensures that the VOP_INACTIVE routine is done with its work. 829 * For active vnodes, it ensures that no other activity can 830 * occur while the buffer list is being cleaned out. 831 */ 832 VOP_LOCK(vp); 833 if (flags & DOCLOSE) 834 vinvalbuf(vp, 1); 835 /* 836 * Prevent any further operations on the vnode from 837 * being passed through to the old file system. 838 */ 839 origops = vp->v_op; 840 vp->v_op = &dead_vnodeops; 841 vp->v_tag = VT_NON; 842 /* 843 * If purging an active vnode, it must be unlocked, closed, 844 * and deactivated before being reclaimed. 845 */ 846 (*(origops->vn_unlock))(vp); 847 if (active) { 848 if (flags & DOCLOSE) 849 (*(origops->vn_close))(vp, IO_NDELAY, NOCRED, p); 850 (*(origops->vn_inactive))(vp, p); 851 } 852 /* 853 * Reclaim the vnode. 854 */ 855 if ((*(origops->vn_reclaim))(vp)) 856 panic("vclean: cannot reclaim"); 857 if (active) 858 vrele(vp); 859 /* 860 * Done with purge, notify sleepers in vget of the grim news. 861 */ 862 vp->v_flag &= ~VXLOCK; 863 if (vp->v_flag & VXWANT) { 864 vp->v_flag &= ~VXWANT; 865 wakeup((caddr_t)vp); 866 } 867 } 868 869 /* 870 * Eliminate all activity associated with the requested vnode 871 * and with all vnodes aliased to the requested vnode. 872 */ 873 void vgoneall(vp) 874 register struct vnode *vp; 875 { 876 register struct vnode *vq; 877 878 if (vp->v_flag & VALIASED) { 879 /* 880 * If a vgone (or vclean) is already in progress, 881 * wait until it is done and return. 882 */ 883 if (vp->v_flag & VXLOCK) { 884 vp->v_flag |= VXWANT; 885 sleep((caddr_t)vp, PINOD); 886 return; 887 } 888 /* 889 * Ensure that vp will not be vgone'd while we 890 * are eliminating its aliases. 891 */ 892 vp->v_flag |= VXLOCK; 893 while (vp->v_flag & VALIASED) { 894 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 895 if (vq->v_rdev != vp->v_rdev || 896 vq->v_type != vp->v_type || vp == vq) 897 continue; 898 vgone(vq); 899 break; 900 } 901 } 902 /* 903 * Remove the lock so that vgone below will 904 * really eliminate the vnode after which time 905 * vgone will awaken any sleepers. 906 */ 907 vp->v_flag &= ~VXLOCK; 908 } 909 vgone(vp); 910 } 911 912 /* 913 * Eliminate all activity associated with a vnode 914 * in preparation for reuse. 915 */ 916 void vgone(vp) 917 register struct vnode *vp; 918 { 919 register struct vnode *vq; 920 struct vnode *vx; 921 long count; 922 923 /* 924 * If a vgone (or vclean) is already in progress, 925 * wait until it is done and return. 926 */ 927 if (vp->v_flag & VXLOCK) { 928 vp->v_flag |= VXWANT; 929 sleep((caddr_t)vp, PINOD); 930 return; 931 } 932 /* 933 * Clean out the filesystem specific data. 934 */ 935 vclean(vp, DOCLOSE); 936 /* 937 * Delete from old mount point vnode list, if on one. 938 */ 939 if (vp->v_mountb) { 940 if (vq = vp->v_mountf) 941 vq->v_mountb = vp->v_mountb; 942 *vp->v_mountb = vq; 943 vp->v_mountf = NULL; 944 vp->v_mountb = NULL; 945 } 946 /* 947 * If special device, remove it from special device alias list. 948 */ 949 if (vp->v_type == VBLK || vp->v_type == VCHR) { 950 if (*vp->v_hashchain == vp) { 951 *vp->v_hashchain = vp->v_specnext; 952 } else { 953 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 954 if (vq->v_specnext != vp) 955 continue; 956 vq->v_specnext = vp->v_specnext; 957 break; 958 } 959 if (vq == NULL) 960 panic("missing bdev"); 961 } 962 if (vp->v_flag & VALIASED) { 963 count = 0; 964 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 965 if (vq->v_rdev != vp->v_rdev || 966 vq->v_type != vp->v_type) 967 continue; 968 count++; 969 vx = vq; 970 } 971 if (count == 0) 972 panic("missing alias"); 973 if (count == 1) 974 vx->v_flag &= ~VALIASED; 975 vp->v_flag &= ~VALIASED; 976 } 977 FREE(vp->v_specinfo, M_VNODE); 978 vp->v_specinfo = NULL; 979 } 980 /* 981 * If it is on the freelist, move it to the head of the list. 982 */ 983 if (vp->v_freeb) { 984 if (vq = vp->v_freef) 985 vq->v_freeb = vp->v_freeb; 986 else 987 vfreet = vp->v_freeb; 988 *vp->v_freeb = vq; 989 vp->v_freef = vfreeh; 990 vp->v_freeb = &vfreeh; 991 vfreeh->v_freeb = &vp->v_freef; 992 vfreeh = vp; 993 } 994 vp->v_type = VBAD; 995 } 996 997 /* 998 * Lookup a vnode by device number. 999 */ 1000 vfinddev(dev, type, vpp) 1001 dev_t dev; 1002 enum vtype type; 1003 struct vnode **vpp; 1004 { 1005 register struct vnode *vp; 1006 1007 for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) { 1008 if (dev != vp->v_rdev || type != vp->v_type) 1009 continue; 1010 *vpp = vp; 1011 return (0); 1012 } 1013 return (1); 1014 } 1015 1016 /* 1017 * Calculate the total number of references to a special device. 1018 */ 1019 vcount(vp) 1020 register struct vnode *vp; 1021 { 1022 register struct vnode *vq; 1023 int count; 1024 1025 if ((vp->v_flag & VALIASED) == 0) 1026 return (vp->v_usecount); 1027 loop: 1028 for (count = 0, vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 1029 if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type) 1030 continue; 1031 /* 1032 * Alias, but not in use, so flush it out. 1033 */ 1034 if (vq->v_usecount == 0) { 1035 vgone(vq); 1036 goto loop; 1037 } 1038 count += vq->v_usecount; 1039 } 1040 return (count); 1041 } 1042 1043 /* 1044 * Print out a description of a vnode. 1045 */ 1046 static char *typename[] = 1047 { "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" }; 1048 1049 vprint(label, vp) 1050 char *label; 1051 register struct vnode *vp; 1052 { 1053 char buf[64]; 1054 1055 if (label != NULL) 1056 printf("%s: ", label); 1057 printf("type %s, usecount %d, refcount %d,", typename[vp->v_type], 1058 vp->v_usecount, vp->v_holdcnt); 1059 buf[0] = '\0'; 1060 if (vp->v_flag & VROOT) 1061 strcat(buf, "|VROOT"); 1062 if (vp->v_flag & VTEXT) 1063 strcat(buf, "|VTEXT"); 1064 if (vp->v_flag & VSYSTEM) 1065 strcat(buf, "|VSYSTEM"); 1066 if (vp->v_flag & VXLOCK) 1067 strcat(buf, "|VXLOCK"); 1068 if (vp->v_flag & VXWANT) 1069 strcat(buf, "|VXWANT"); 1070 if (vp->v_flag & VBWAIT) 1071 strcat(buf, "|VBWAIT"); 1072 if (vp->v_flag & VALIASED) 1073 strcat(buf, "|VALIASED"); 1074 if (buf[0] != '\0') 1075 printf(" flags (%s)", &buf[1]); 1076 printf("\n\t"); 1077 VOP_PRINT(vp); 1078 } 1079 1080 #ifdef DEBUG 1081 /* 1082 * List all of the locked vnodes in the system. 1083 * Called when debugging the kernel. 1084 */ 1085 printlockedvnodes() 1086 { 1087 register struct mount *mp; 1088 register struct vnode *vp; 1089 1090 printf("Locked vnodes\n"); 1091 mp = rootfs; 1092 do { 1093 for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) 1094 if (VOP_ISLOCKED(vp)) 1095 vprint((char *)0, vp); 1096 mp = mp->mnt_next; 1097 } while (mp != rootfs); 1098 } 1099 #endif 1100 1101 int kinfo_vdebug = 1; 1102 int kinfo_vgetfailed; 1103 #define KINFO_VNODESLOP 10 1104 /* 1105 * Dump vnode list (via kinfo). 1106 * Copyout address of vnode followed by vnode. 1107 */ 1108 /* ARGSUSED */ 1109 kinfo_vnode(op, where, acopysize, arg, aneeded) 1110 int op; 1111 char *where; 1112 int *acopysize, arg, *aneeded; 1113 { 1114 register struct mount *mp = rootfs; 1115 struct mount *omp; 1116 struct vnode *vp; 1117 register char *bp = where, *savebp; 1118 char *ewhere = where + *acopysize; 1119 int error; 1120 1121 #define VPTRSZ sizeof (struct vnode *) 1122 #define VNODESZ sizeof (struct vnode) 1123 if (where == NULL) { 1124 *aneeded = (numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ); 1125 return (0); 1126 } 1127 1128 do { 1129 if (vfs_busy(mp)) { 1130 mp = mp->mnt_next; 1131 continue; 1132 } 1133 savebp = bp; 1134 again: 1135 for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) { 1136 /* 1137 * Check that the vp is still associated with 1138 * this filesystem. RACE: could have been 1139 * recycled onto the same filesystem. 1140 */ 1141 if (vp->v_mount != mp) { 1142 if (kinfo_vdebug) 1143 printf("kinfo: vp changed\n"); 1144 bp = savebp; 1145 goto again; 1146 } 1147 if ((bp + VPTRSZ + VNODESZ <= ewhere) && 1148 ((error = copyout((caddr_t)&vp, bp, VPTRSZ)) || 1149 (error = copyout((caddr_t)vp, bp + VPTRSZ, 1150 VNODESZ)))) 1151 return (error); 1152 bp += VPTRSZ + VNODESZ; 1153 } 1154 omp = mp; 1155 mp = mp->mnt_next; 1156 vfs_unbusy(omp); 1157 } while (mp != rootfs); 1158 1159 *aneeded = bp - where; 1160 if (bp > ewhere) 1161 *acopysize = ewhere - where; 1162 else 1163 *acopysize = bp - where; 1164 return (0); 1165 } 1166