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