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