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