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.99 (Berkeley) 04/28/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 vp->v_usecount++; 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 vp->v_usecount++; 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 if (vp->v_usecount <= 0) 597 panic("vref used where vget required"); 598 vp->v_usecount++; 599 } 600 601 /* 602 * vput(), just unlock and vrele() 603 */ 604 void vput(vp) 605 register struct vnode *vp; 606 { 607 608 VOP_UNLOCK(vp); 609 vrele(vp); 610 } 611 612 /* 613 * Vnode release. 614 * If count drops to zero, call inactive routine and return to freelist. 615 */ 616 void vrele(vp) 617 register struct vnode *vp; 618 { 619 620 #ifdef DIAGNOSTIC 621 if (vp == NULL) 622 panic("vrele: null vp"); 623 #endif 624 vp->v_usecount--; 625 if (vp->v_usecount > 0) 626 return; 627 #ifdef DIAGNOSTIC 628 if (vp->v_usecount != 0 || vp->v_writecount != 0) { 629 vprint("vrele: bad ref count", vp); 630 panic("vrele: ref cnt"); 631 } 632 #endif 633 /* 634 * insert at tail of LRU list 635 */ 636 *vfreet = vp; 637 vp->v_freeb = vfreet; 638 vp->v_freef = NULL; 639 vfreet = &vp->v_freef; 640 VOP_INACTIVE(vp); 641 } 642 643 /* 644 * Page or buffer structure gets a reference. 645 */ 646 void vhold(vp) 647 register struct vnode *vp; 648 { 649 650 vp->v_holdcnt++; 651 } 652 653 /* 654 * Page or buffer structure frees a reference. 655 */ 656 void holdrele(vp) 657 register struct vnode *vp; 658 { 659 660 if (vp->v_holdcnt <= 0) 661 panic("holdrele: holdcnt"); 662 vp->v_holdcnt--; 663 } 664 665 /* 666 * Remove any vnodes in the vnode table belonging to mount point mp. 667 * 668 * If MNT_NOFORCE is specified, there should not be any active ones, 669 * return error if any are found (nb: this is a user error, not a 670 * system error). If MNT_FORCE is specified, detach any active vnodes 671 * that are found. 672 */ 673 int busyprt = 0; /* patch to print out busy vnodes */ 674 675 vflush(mp, skipvp, flags) 676 struct mount *mp; 677 struct vnode *skipvp; 678 int flags; 679 { 680 register struct vnode *vp, *nvp; 681 int busy = 0; 682 683 if ((mp->mnt_flag & MNT_MPBUSY) == 0) 684 panic("vflush: not busy"); 685 loop: 686 for (vp = mp->mnt_mounth; vp; vp = nvp) { 687 if (vp->v_mount != mp) 688 goto loop; 689 nvp = vp->v_mountf; 690 /* 691 * Skip over a selected vnode. 692 */ 693 if (vp == skipvp) 694 continue; 695 /* 696 * Skip over a vnodes marked VSYSTEM. 697 */ 698 if ((flags & SKIPSYSTEM) && (vp->v_flag & VSYSTEM)) 699 continue; 700 /* 701 * If WRITECLOSE is set, only flush out regular file 702 * vnodes open for writing. 703 */ 704 if ((flags & WRITECLOSE) && 705 (vp->v_writecount == 0 || vp->v_type != VREG)) 706 continue; 707 /* 708 * With v_usecount == 0, all we need to do is clear 709 * out the vnode data structures and we are done. 710 */ 711 if (vp->v_usecount == 0) { 712 vgone(vp); 713 continue; 714 } 715 /* 716 * If FORCECLOSE is set, forcibly close the vnode. 717 * For block or character devices, revert to an 718 * anonymous device. For all other files, just kill them. 719 */ 720 if (flags & FORCECLOSE) { 721 if (vp->v_type != VBLK && vp->v_type != VCHR) { 722 vgone(vp); 723 } else { 724 vclean(vp, 0); 725 vp->v_op = spec_vnodeop_p; 726 insmntque(vp, (struct mount *)0); 727 } 728 continue; 729 } 730 if (busyprt) 731 vprint("vflush: busy vnode", vp); 732 busy++; 733 } 734 if (busy) 735 return (EBUSY); 736 return (0); 737 } 738 739 /* 740 * Disassociate the underlying file system from a vnode. 741 */ 742 void 743 vclean(vp, flags) 744 register struct vnode *vp; 745 int flags; 746 { 747 int active; 748 749 /* 750 * Check to see if the vnode is in use. 751 * If so we have to reference it before we clean it out 752 * so that its count cannot fall to zero and generate a 753 * race against ourselves to recycle it. 754 */ 755 if (active = vp->v_usecount) 756 VREF(vp); 757 /* 758 * Even if the count is zero, the VOP_INACTIVE routine may still 759 * have the object locked while it cleans it out. The VOP_LOCK 760 * ensures that the VOP_INACTIVE routine is done with its work. 761 * For active vnodes, it ensures that no other activity can 762 * occur while the underlying object is being cleaned out. 763 */ 764 VOP_LOCK(vp); 765 /* 766 * Prevent the vnode from being recycled or 767 * brought into use while we clean it out. 768 */ 769 if (vp->v_flag & VXLOCK) 770 panic("vclean: deadlock"); 771 vp->v_flag |= VXLOCK; 772 /* 773 * Clean out any buffers associated with the vnode. 774 */ 775 if (flags & DOCLOSE) 776 vinvalbuf(vp, V_SAVE, NOCRED, NULL, 0, 0); 777 /* 778 * Any other processes trying to obtain this lock must first 779 * wait for VXLOCK to clear, then call the new lock operation. 780 */ 781 VOP_UNLOCK(vp); 782 /* 783 * If purging an active vnode, it must be closed and 784 * deactivated before being reclaimed. 785 */ 786 if (active) { 787 if (flags & DOCLOSE) 788 VOP_CLOSE(vp, IO_NDELAY, NOCRED, NULL); 789 VOP_INACTIVE(vp); 790 } 791 /* 792 * Reclaim the vnode. 793 */ 794 if (VOP_RECLAIM(vp)) 795 panic("vclean: cannot reclaim"); 796 if (active) 797 vrele(vp); 798 799 /* 800 * Done with purge, notify sleepers of the grim news. 801 */ 802 vp->v_op = dead_vnodeop_p; 803 vp->v_tag = VT_NON; 804 vp->v_flag &= ~VXLOCK; 805 if (vp->v_flag & VXWANT) { 806 vp->v_flag &= ~VXWANT; 807 wakeup((caddr_t)vp); 808 } 809 } 810 811 /* 812 * Eliminate all activity associated with the requested vnode 813 * and with all vnodes aliased to the requested vnode. 814 */ 815 void vgoneall(vp) 816 register struct vnode *vp; 817 { 818 register struct vnode *vq; 819 820 if (vp->v_flag & VALIASED) { 821 /* 822 * If a vgone (or vclean) is already in progress, 823 * wait until it is done and return. 824 */ 825 if (vp->v_flag & VXLOCK) { 826 vp->v_flag |= VXWANT; 827 sleep((caddr_t)vp, PINOD); 828 return; 829 } 830 /* 831 * Ensure that vp will not be vgone'd while we 832 * are eliminating its aliases. 833 */ 834 vp->v_flag |= VXLOCK; 835 while (vp->v_flag & VALIASED) { 836 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 837 if (vq->v_rdev != vp->v_rdev || 838 vq->v_type != vp->v_type || vp == vq) 839 continue; 840 vgone(vq); 841 break; 842 } 843 } 844 /* 845 * Remove the lock so that vgone below will 846 * really eliminate the vnode after which time 847 * vgone will awaken any sleepers. 848 */ 849 vp->v_flag &= ~VXLOCK; 850 } 851 vgone(vp); 852 } 853 854 /* 855 * Eliminate all activity associated with a vnode 856 * in preparation for reuse. 857 */ 858 void vgone(vp) 859 register struct vnode *vp; 860 { 861 register struct vnode *vq; 862 struct vnode *vx; 863 864 /* 865 * If a vgone (or vclean) is already in progress, 866 * wait until it is done and return. 867 */ 868 if (vp->v_flag & VXLOCK) { 869 vp->v_flag |= VXWANT; 870 sleep((caddr_t)vp, PINOD); 871 return; 872 } 873 /* 874 * Clean out the filesystem specific data. 875 */ 876 vclean(vp, DOCLOSE); 877 /* 878 * Delete from old mount point vnode list, if on one. 879 */ 880 if (vp->v_mountb) { 881 if (vq = vp->v_mountf) 882 vq->v_mountb = vp->v_mountb; 883 *vp->v_mountb = vq; 884 vp->v_mountf = NULL; 885 vp->v_mountb = NULL; 886 vp->v_mount = NULL; 887 } 888 /* 889 * If special device, remove it from special device alias list. 890 */ 891 if (vp->v_type == VBLK || vp->v_type == VCHR) { 892 if (*vp->v_hashchain == vp) { 893 *vp->v_hashchain = vp->v_specnext; 894 } else { 895 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 896 if (vq->v_specnext != vp) 897 continue; 898 vq->v_specnext = vp->v_specnext; 899 break; 900 } 901 if (vq == NULL) 902 panic("missing bdev"); 903 } 904 if (vp->v_flag & VALIASED) { 905 vx = NULL; 906 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 907 if (vq->v_rdev != vp->v_rdev || 908 vq->v_type != vp->v_type) 909 continue; 910 if (vx) 911 break; 912 vx = vq; 913 } 914 if (vx == NULL) 915 panic("missing alias"); 916 if (vq == NULL) 917 vx->v_flag &= ~VALIASED; 918 vp->v_flag &= ~VALIASED; 919 } 920 FREE(vp->v_specinfo, M_VNODE); 921 vp->v_specinfo = NULL; 922 } 923 /* 924 * If it is on the freelist and not already at the head, 925 * move it to the head of the list. 926 */ 927 if (vp->v_freeb && vfreeh != vp) { 928 if (vq = vp->v_freef) 929 vq->v_freeb = vp->v_freeb; 930 else 931 vfreet = vp->v_freeb; 932 *vp->v_freeb = vq; 933 vp->v_freef = vfreeh; 934 vp->v_freeb = &vfreeh; 935 vfreeh->v_freeb = &vp->v_freef; 936 vfreeh = vp; 937 } 938 vp->v_type = VBAD; 939 } 940 941 /* 942 * Lookup a vnode by device number. 943 */ 944 vfinddev(dev, type, vpp) 945 dev_t dev; 946 enum vtype type; 947 struct vnode **vpp; 948 { 949 register struct vnode *vp; 950 951 for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) { 952 if (dev != vp->v_rdev || type != vp->v_type) 953 continue; 954 *vpp = vp; 955 return (1); 956 } 957 return (0); 958 } 959 960 /* 961 * Calculate the total number of references to a special device. 962 */ 963 vcount(vp) 964 register struct vnode *vp; 965 { 966 register struct vnode *vq; 967 int count; 968 969 if ((vp->v_flag & VALIASED) == 0) 970 return (vp->v_usecount); 971 loop: 972 for (count = 0, vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 973 if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type) 974 continue; 975 /* 976 * Alias, but not in use, so flush it out. 977 */ 978 if (vq->v_usecount == 0) { 979 vgone(vq); 980 goto loop; 981 } 982 count += vq->v_usecount; 983 } 984 return (count); 985 } 986 987 /* 988 * Print out a description of a vnode. 989 */ 990 static char *typename[] = 991 { "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" }; 992 993 vprint(label, vp) 994 char *label; 995 register struct vnode *vp; 996 { 997 char buf[64]; 998 999 if (label != NULL) 1000 printf("%s: ", label); 1001 printf("type %s, usecount %d, writecount %d, refcount %d,", 1002 typename[vp->v_type], vp->v_usecount, vp->v_writecount, 1003 vp->v_holdcnt); 1004 buf[0] = '\0'; 1005 if (vp->v_flag & VROOT) 1006 strcat(buf, "|VROOT"); 1007 if (vp->v_flag & VTEXT) 1008 strcat(buf, "|VTEXT"); 1009 if (vp->v_flag & VSYSTEM) 1010 strcat(buf, "|VSYSTEM"); 1011 if (vp->v_flag & VXLOCK) 1012 strcat(buf, "|VXLOCK"); 1013 if (vp->v_flag & VXWANT) 1014 strcat(buf, "|VXWANT"); 1015 if (vp->v_flag & VBWAIT) 1016 strcat(buf, "|VBWAIT"); 1017 if (vp->v_flag & VALIASED) 1018 strcat(buf, "|VALIASED"); 1019 if (buf[0] != '\0') 1020 printf(" flags (%s)", &buf[1]); 1021 printf("\n\t"); 1022 VOP_PRINT(vp); 1023 } 1024 1025 #ifdef DEBUG 1026 /* 1027 * List all of the locked vnodes in the system. 1028 * Called when debugging the kernel. 1029 */ 1030 printlockedvnodes() 1031 { 1032 register struct mount *mp; 1033 register struct vnode *vp; 1034 1035 printf("Locked vnodes\n"); 1036 mp = rootfs; 1037 do { 1038 for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) 1039 if (VOP_ISLOCKED(vp)) 1040 vprint((char *)0, vp); 1041 mp = mp->mnt_next; 1042 } while (mp != rootfs); 1043 } 1044 #endif 1045 1046 int kinfo_vdebug = 1; 1047 int kinfo_vgetfailed; 1048 #define KINFO_VNODESLOP 10 1049 /* 1050 * Dump vnode list (via sysctl). 1051 * Copyout address of vnode followed by vnode. 1052 */ 1053 /* ARGSUSED */ 1054 sysctl_vnode(where, sizep) 1055 char *where; 1056 size_t *sizep; 1057 { 1058 register struct mount *mp = rootfs; 1059 struct mount *omp; 1060 struct vnode *vp; 1061 register char *bp = where, *savebp; 1062 char *ewhere; 1063 int error; 1064 1065 #define VPTRSZ sizeof (struct vnode *) 1066 #define VNODESZ sizeof (struct vnode) 1067 if (where == NULL) { 1068 *sizep = (numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ); 1069 return (0); 1070 } 1071 ewhere = where + *sizep; 1072 1073 do { 1074 if (vfs_busy(mp)) { 1075 mp = mp->mnt_next; 1076 continue; 1077 } 1078 savebp = bp; 1079 again: 1080 for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) { 1081 /* 1082 * Check that the vp is still associated with 1083 * this filesystem. RACE: could have been 1084 * recycled onto the same filesystem. 1085 */ 1086 if (vp->v_mount != mp) { 1087 if (kinfo_vdebug) 1088 printf("kinfo: vp changed\n"); 1089 bp = savebp; 1090 goto again; 1091 } 1092 if (bp + VPTRSZ + VNODESZ > ewhere) { 1093 *sizep = bp - where; 1094 return (ENOMEM); 1095 } 1096 if ((error = copyout((caddr_t)&vp, bp, VPTRSZ)) || 1097 (error = copyout((caddr_t)vp, bp + VPTRSZ, VNODESZ))) 1098 return (error); 1099 bp += VPTRSZ + VNODESZ; 1100 } 1101 omp = mp; 1102 mp = mp->mnt_next; 1103 vfs_unbusy(omp); 1104 } while (mp != rootfs); 1105 1106 *sizep = bp - where; 1107 return (0); 1108 } 1109