1 /* $NetBSD: vfs_subr.c,v 1.51 1996/02/09 19:01:01 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * (c) UNIX System Laboratories, Inc. 7 * All or some portions of this file are derived from material licensed 8 * to the University of California by American Telephone and Telegraph 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 * the permission of UNIX System Laboratories, Inc. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 41 */ 42 43 /* 44 * External virtual filesystem routines 45 */ 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/proc.h> 50 #include <sys/mount.h> 51 #include <sys/time.h> 52 #include <sys/fcntl.h> 53 #include <sys/vnode.h> 54 #include <sys/stat.h> 55 #include <sys/namei.h> 56 #include <sys/ucred.h> 57 #include <sys/buf.h> 58 #include <sys/errno.h> 59 #include <sys/malloc.h> 60 #include <sys/domain.h> 61 #include <sys/mbuf.h> 62 #include <sys/syscallargs.h> 63 #include <sys/cpu.h> 64 65 #include <vm/vm.h> 66 #include <sys/sysctl.h> 67 68 #include <miscfs/specfs/specdev.h> 69 70 enum vtype iftovt_tab[16] = { 71 VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON, 72 VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD, 73 }; 74 int vttoif_tab[9] = { 75 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, 76 S_IFSOCK, S_IFIFO, S_IFMT, 77 }; 78 79 int doforce = 1; /* 1 => permit forcible unmounting */ 80 int prtactive = 0; /* 1 => print out reclaim of active vnodes */ 81 82 /* 83 * Insq/Remq for the vnode usage lists. 84 */ 85 #define bufinsvn(bp, dp) LIST_INSERT_HEAD(dp, bp, b_vnbufs) 86 #define bufremvn(bp) { \ 87 LIST_REMOVE(bp, b_vnbufs); \ 88 (bp)->b_vnbufs.le_next = NOLIST; \ 89 } 90 TAILQ_HEAD(freelst, vnode) vnode_free_list; /* vnode free list */ 91 struct mntlist mountlist; /* mounted filesystem list */ 92 93 int vfs_lock __P((struct mount *)); 94 void vfs_unlock __P((struct mount *)); 95 struct mount *getvfs __P((fsid_t *)); 96 long makefstype __P((char *)); 97 void vattr_null __P((struct vattr *)); 98 int getnewvnode __P((enum vtagtype, struct mount *, int (**)(void *), 99 struct vnode **)); 100 void insmntque __P((struct vnode *, struct mount *)); 101 int vinvalbuf __P((struct vnode *, int, struct ucred *, struct proc *, int, 102 int)); 103 void vflushbuf __P((struct vnode *, int)); 104 void brelvp __P((struct buf *)); 105 int bdevvp __P((dev_t, struct vnode **)); 106 int cdevvp __P((dev_t, struct vnode **)); 107 int getdevvp __P((dev_t, struct vnode **, enum vtype)); 108 struct vnode *checkalias __P((struct vnode *, dev_t, struct mount *)); 109 int vget __P((struct vnode *, int)); 110 void vref __P((struct vnode *)); 111 void vput __P((struct vnode *)); 112 void vrele __P((struct vnode *)); 113 void vhold __P((struct vnode *)); 114 void holdrele __P((struct vnode *)); 115 int vflush __P((struct mount *, struct vnode *, int)); 116 void vgoneall __P((struct vnode *)); 117 void vgone __P((struct vnode *)); 118 int vcount __P((struct vnode *)); 119 void vprint __P((char *, struct vnode *)); 120 int vfs_mountedon __P((struct vnode *)); 121 int vfs_export __P((struct mount *, struct netexport *, struct export_args *)); 122 struct netcred *vfs_export_lookup __P((struct mount *, struct netexport *, 123 struct mbuf *)); 124 int vaccess __P((mode_t, uid_t, gid_t, mode_t, struct ucred *)); 125 void vfs_unmountall __P((void)); 126 void vfs_shutdown __P((void)); 127 128 static int vfs_hang_addrlist __P((struct mount *, struct netexport *, 129 struct export_args *)); 130 static int vfs_free_netcred __P((struct radix_node *, void *)); 131 static void vfs_free_addrlist __P((struct netexport *)); 132 133 #ifdef DEBUG 134 void printlockedvnodes __P((void)); 135 #endif 136 137 /* 138 * Initialize the vnode management data structures. 139 */ 140 void 141 vntblinit() 142 { 143 144 TAILQ_INIT(&vnode_free_list); 145 CIRCLEQ_INIT(&mountlist); 146 } 147 148 /* 149 * Lock a filesystem. 150 * Used to prevent access to it while mounting and unmounting. 151 */ 152 int 153 vfs_lock(mp) 154 register struct mount *mp; 155 { 156 157 while (mp->mnt_flag & MNT_MLOCK) { 158 mp->mnt_flag |= MNT_MWAIT; 159 tsleep((caddr_t)mp, PVFS, "vfslock", 0); 160 } 161 mp->mnt_flag |= MNT_MLOCK; 162 return (0); 163 } 164 165 /* 166 * Unlock a locked filesystem. 167 * Panic if filesystem is not locked. 168 */ 169 void 170 vfs_unlock(mp) 171 register struct mount *mp; 172 { 173 174 if ((mp->mnt_flag & MNT_MLOCK) == 0) 175 panic("vfs_unlock: not locked"); 176 mp->mnt_flag &= ~MNT_MLOCK; 177 if (mp->mnt_flag & MNT_MWAIT) { 178 mp->mnt_flag &= ~MNT_MWAIT; 179 wakeup((caddr_t)mp); 180 } 181 } 182 183 /* 184 * Mark a mount point as busy. 185 * Used to synchronize access and to delay unmounting. 186 */ 187 int 188 vfs_busy(mp) 189 register struct mount *mp; 190 { 191 192 while(mp->mnt_flag & MNT_MPBUSY) { 193 mp->mnt_flag |= MNT_MPWANT; 194 tsleep((caddr_t)&mp->mnt_flag, PVFS, "vfsbusy", 0); 195 } 196 if (mp->mnt_flag & MNT_UNMOUNT) 197 return (1); 198 mp->mnt_flag |= MNT_MPBUSY; 199 return (0); 200 } 201 202 /* 203 * Free a busy filesystem. 204 * Panic if filesystem is not busy. 205 */ 206 void 207 vfs_unbusy(mp) 208 register struct mount *mp; 209 { 210 211 if ((mp->mnt_flag & MNT_MPBUSY) == 0) 212 panic("vfs_unbusy: not busy"); 213 mp->mnt_flag &= ~MNT_MPBUSY; 214 if (mp->mnt_flag & MNT_MPWANT) { 215 mp->mnt_flag &= ~MNT_MPWANT; 216 wakeup((caddr_t)&mp->mnt_flag); 217 } 218 } 219 220 /* 221 * Lookup a mount point by filesystem identifier. 222 */ 223 struct mount * 224 getvfs(fsid) 225 fsid_t *fsid; 226 { 227 register struct mount *mp; 228 229 for (mp = mountlist.cqh_first; mp != (void *)&mountlist; 230 mp = mp->mnt_list.cqe_next) 231 if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] && 232 mp->mnt_stat.f_fsid.val[1] == fsid->val[1]) 233 return (mp); 234 return ((struct mount *)0); 235 } 236 237 /* 238 * Get a new unique fsid 239 */ 240 void 241 getnewfsid(mp, mtype) 242 struct mount *mp; 243 int mtype; 244 { 245 static u_short xxxfs_mntid; 246 247 fsid_t tfsid; 248 249 mp->mnt_stat.f_fsid.val[0] = makedev(nblkdev + 11, 0); /* XXX */ 250 mp->mnt_stat.f_fsid.val[1] = mtype; 251 if (xxxfs_mntid == 0) 252 ++xxxfs_mntid; 253 tfsid.val[0] = makedev((nblkdev + mtype) & 0xff, xxxfs_mntid); 254 tfsid.val[1] = mtype; 255 if (mountlist.cqh_first != (void *)&mountlist) { 256 while (getvfs(&tfsid)) { 257 tfsid.val[0]++; 258 xxxfs_mntid++; 259 } 260 } 261 mp->mnt_stat.f_fsid.val[0] = tfsid.val[0]; 262 } 263 264 /* 265 * Make a 'unique' number from a mount type name. 266 */ 267 long 268 makefstype(type) 269 char *type; 270 { 271 long rv; 272 273 for (rv = 0; *type; type++) { 274 rv <<= 2; 275 rv ^= *type; 276 } 277 return rv; 278 } 279 280 /* 281 * Set vnode attributes to VNOVAL 282 */ 283 void 284 vattr_null(vap) 285 register struct vattr *vap; 286 { 287 288 vap->va_type = VNON; 289 /* XXX These next two used to be one line, but for a GCC bug. */ 290 vap->va_size = VNOVAL; 291 vap->va_bytes = VNOVAL; 292 vap->va_mode = vap->va_nlink = vap->va_uid = vap->va_gid = 293 vap->va_fsid = vap->va_fileid = 294 vap->va_blocksize = vap->va_rdev = 295 vap->va_atime.tv_sec = vap->va_atime.tv_nsec = 296 vap->va_mtime.tv_sec = vap->va_mtime.tv_nsec = 297 vap->va_ctime.tv_sec = vap->va_ctime.tv_nsec = 298 vap->va_flags = vap->va_gen = VNOVAL; 299 vap->va_vaflags = 0; 300 } 301 302 /* 303 * Routines having to do with the management of the vnode table. 304 */ 305 extern int (**dead_vnodeop_p) __P((void *)); 306 long numvnodes; 307 308 /* 309 * Return the next vnode from the free list. 310 */ 311 int 312 getnewvnode(tag, mp, vops, vpp) 313 enum vtagtype tag; 314 struct mount *mp; 315 int (**vops) __P((void *)); 316 struct vnode **vpp; 317 { 318 register struct vnode *vp; 319 #ifdef DIAGNOSTIC 320 int s; 321 #endif 322 323 if ((vnode_free_list.tqh_first == NULL && 324 numvnodes < 2 * desiredvnodes) || 325 numvnodes < desiredvnodes) { 326 vp = (struct vnode *)malloc((u_long)sizeof *vp, 327 M_VNODE, M_WAITOK); 328 bzero((char *)vp, sizeof *vp); 329 numvnodes++; 330 } else { 331 if ((vp = vnode_free_list.tqh_first) == NULL) { 332 tablefull("vnode"); 333 *vpp = 0; 334 return (ENFILE); 335 } 336 if (vp->v_usecount) { 337 vprint("free vnode", vp); 338 panic("free vnode isn't"); 339 } 340 TAILQ_REMOVE(&vnode_free_list, vp, v_freelist); 341 /* see comment on why 0xdeadb is set at end of vgone (below) */ 342 vp->v_freelist.tqe_prev = (struct vnode **)0xdeadb; 343 vp->v_lease = NULL; 344 if (vp->v_type != VBAD) 345 vgone(vp); 346 #ifdef DIAGNOSTIC 347 if (vp->v_data) { 348 vprint("cleaned vnode", vp); 349 panic("cleaned vnode isn't"); 350 } 351 s = splbio(); 352 if (vp->v_numoutput) 353 panic("Clean vnode has pending I/O's"); 354 splx(s); 355 #endif 356 vp->v_flag = 0; 357 vp->v_lastr = 0; 358 vp->v_ralen = 0; 359 vp->v_maxra = 0; 360 vp->v_lastw = 0; 361 vp->v_lasta = 0; 362 vp->v_cstart = 0; 363 vp->v_clen = 0; 364 vp->v_socket = 0; 365 } 366 vp->v_type = VNON; 367 cache_purge(vp); 368 vp->v_tag = tag; 369 vp->v_op = vops; 370 insmntque(vp, mp); 371 *vpp = vp; 372 vp->v_usecount = 1; 373 vp->v_data = 0; 374 return (0); 375 } 376 377 /* 378 * Move a vnode from one mount queue to another. 379 */ 380 void 381 insmntque(vp, mp) 382 register struct vnode *vp; 383 register struct mount *mp; 384 { 385 386 /* 387 * Delete from old mount point vnode list, if on one. 388 */ 389 if (vp->v_mount != NULL) 390 LIST_REMOVE(vp, v_mntvnodes); 391 /* 392 * Insert into list of vnodes for the new mount point, if available. 393 */ 394 if ((vp->v_mount = mp) == NULL) 395 return; 396 LIST_INSERT_HEAD(&mp->mnt_vnodelist, vp, v_mntvnodes); 397 } 398 399 /* 400 * Update outstanding I/O count and do wakeup if requested. 401 */ 402 void 403 vwakeup(bp) 404 register struct buf *bp; 405 { 406 register struct vnode *vp; 407 408 bp->b_flags &= ~B_WRITEINPROG; 409 if ((vp = bp->b_vp) != NULL) { 410 if (--vp->v_numoutput < 0) 411 panic("vwakeup: neg numoutput"); 412 if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) { 413 vp->v_flag &= ~VBWAIT; 414 wakeup((caddr_t)&vp->v_numoutput); 415 } 416 } 417 } 418 419 /* 420 * Flush out and invalidate all buffers associated with a vnode. 421 * Called with the underlying object locked. 422 */ 423 int 424 vinvalbuf(vp, flags, cred, p, slpflag, slptimeo) 425 register struct vnode *vp; 426 int flags; 427 struct ucred *cred; 428 struct proc *p; 429 int slpflag, slptimeo; 430 { 431 register struct buf *bp; 432 struct buf *nbp, *blist; 433 int s, error; 434 435 if (flags & V_SAVE) { 436 if ((error = VOP_FSYNC(vp, cred, MNT_WAIT, p)) != 0) 437 return (error); 438 if (vp->v_dirtyblkhd.lh_first != NULL) 439 panic("vinvalbuf: dirty bufs"); 440 } 441 for (;;) { 442 if ((blist = vp->v_cleanblkhd.lh_first) && flags & V_SAVEMETA) 443 while (blist && blist->b_lblkno < 0) 444 blist = blist->b_vnbufs.le_next; 445 if (!blist && (blist = vp->v_dirtyblkhd.lh_first) && 446 (flags & V_SAVEMETA)) 447 while (blist && blist->b_lblkno < 0) 448 blist = blist->b_vnbufs.le_next; 449 if (!blist) 450 break; 451 452 for (bp = blist; bp; bp = nbp) { 453 nbp = bp->b_vnbufs.le_next; 454 if (flags & V_SAVEMETA && bp->b_lblkno < 0) 455 continue; 456 s = splbio(); 457 if (bp->b_flags & B_BUSY) { 458 bp->b_flags |= B_WANTED; 459 error = tsleep((caddr_t)bp, 460 slpflag | (PRIBIO + 1), "vinvalbuf", 461 slptimeo); 462 splx(s); 463 if (error) 464 return (error); 465 break; 466 } 467 bremfree(bp); 468 bp->b_flags |= B_BUSY; 469 splx(s); 470 /* 471 * XXX Since there are no node locks for NFS, I believe 472 * there is a slight chance that a delayed write will 473 * occur while sleeping just above, so check for it. 474 */ 475 if ((bp->b_flags & B_DELWRI) && (flags & V_SAVE)) { 476 (void) VOP_BWRITE(bp); 477 break; 478 } 479 bp->b_flags |= B_INVAL; 480 brelse(bp); 481 } 482 } 483 if (!(flags & V_SAVEMETA) && 484 (vp->v_dirtyblkhd.lh_first || vp->v_cleanblkhd.lh_first)) 485 panic("vinvalbuf: flush failed"); 486 return (0); 487 } 488 489 void 490 vflushbuf(vp, sync) 491 register struct vnode *vp; 492 int sync; 493 { 494 register struct buf *bp, *nbp; 495 int s; 496 497 loop: 498 s = splbio(); 499 for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) { 500 nbp = bp->b_vnbufs.le_next; 501 if ((bp->b_flags & B_BUSY)) 502 continue; 503 if ((bp->b_flags & B_DELWRI) == 0) 504 panic("vflushbuf: not dirty"); 505 bremfree(bp); 506 bp->b_flags |= B_BUSY; 507 splx(s); 508 /* 509 * Wait for I/O associated with indirect blocks to complete, 510 * since there is no way to quickly wait for them below. 511 */ 512 if (bp->b_vp == vp || sync == 0) 513 (void) bawrite(bp); 514 else 515 (void) bwrite(bp); 516 goto loop; 517 } 518 if (sync == 0) { 519 splx(s); 520 return; 521 } 522 while (vp->v_numoutput) { 523 vp->v_flag |= VBWAIT; 524 tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "vflushbuf", 0); 525 } 526 splx(s); 527 if (vp->v_dirtyblkhd.lh_first != NULL) { 528 vprint("vflushbuf: dirty", vp); 529 goto loop; 530 } 531 } 532 533 /* 534 * Associate a buffer with a vnode. 535 */ 536 void 537 bgetvp(vp, bp) 538 register struct vnode *vp; 539 register struct buf *bp; 540 { 541 542 if (bp->b_vp) 543 panic("bgetvp: not free"); 544 VHOLD(vp); 545 bp->b_vp = vp; 546 if (vp->v_type == VBLK || vp->v_type == VCHR) 547 bp->b_dev = vp->v_rdev; 548 else 549 bp->b_dev = NODEV; 550 /* 551 * Insert onto list for new vnode. 552 */ 553 bufinsvn(bp, &vp->v_cleanblkhd); 554 } 555 556 /* 557 * Disassociate a buffer from a vnode. 558 */ 559 void 560 brelvp(bp) 561 register struct buf *bp; 562 { 563 struct vnode *vp; 564 565 if (bp->b_vp == (struct vnode *) 0) 566 panic("brelvp: NULL"); 567 /* 568 * Delete from old vnode list, if on one. 569 */ 570 if (bp->b_vnbufs.le_next != NOLIST) 571 bufremvn(bp); 572 vp = bp->b_vp; 573 bp->b_vp = (struct vnode *) 0; 574 HOLDRELE(vp); 575 } 576 577 /* 578 * Reassign a buffer from one vnode to another. 579 * Used to assign file specific control information 580 * (indirect blocks) to the vnode to which they belong. 581 */ 582 void 583 reassignbuf(bp, newvp) 584 register struct buf *bp; 585 register struct vnode *newvp; 586 { 587 register struct buflists *listheadp; 588 589 if (newvp == NULL) { 590 printf("reassignbuf: NULL"); 591 return; 592 } 593 /* 594 * Delete from old vnode list, if on one. 595 */ 596 if (bp->b_vnbufs.le_next != NOLIST) 597 bufremvn(bp); 598 /* 599 * If dirty, put on list of dirty buffers; 600 * otherwise insert onto list of clean buffers. 601 */ 602 if (bp->b_flags & B_DELWRI) 603 listheadp = &newvp->v_dirtyblkhd; 604 else 605 listheadp = &newvp->v_cleanblkhd; 606 bufinsvn(bp, listheadp); 607 } 608 609 /* 610 * Create a vnode for a block device. 611 * Used for root filesystem, argdev, and swap areas. 612 * Also used for memory file system special devices. 613 */ 614 int 615 bdevvp(dev, vpp) 616 dev_t dev; 617 struct vnode **vpp; 618 { 619 620 return (getdevvp(dev, vpp, VBLK)); 621 } 622 623 /* 624 * Create a vnode for a character device. 625 * Used for kernfs and some console handling. 626 */ 627 int 628 cdevvp(dev, vpp) 629 dev_t dev; 630 struct vnode **vpp; 631 { 632 633 return (getdevvp(dev, vpp, VCHR)); 634 } 635 636 /* 637 * Create a vnode for a device. 638 * Used by bdevvp (block device) for root file system etc., 639 * and by cdevvp (character device) for console and kernfs. 640 */ 641 int 642 getdevvp(dev, vpp, type) 643 dev_t dev; 644 struct vnode **vpp; 645 enum vtype type; 646 { 647 register struct vnode *vp; 648 struct vnode *nvp; 649 int error; 650 651 if (dev == NODEV) 652 return (0); 653 error = getnewvnode(VT_NON, NULL, spec_vnodeop_p, &nvp); 654 if (error) { 655 *vpp = NULLVP; 656 return (error); 657 } 658 vp = nvp; 659 vp->v_type = type; 660 if ((nvp = checkalias(vp, dev, NULL)) != 0) { 661 vput(vp); 662 vp = nvp; 663 } 664 *vpp = vp; 665 return (0); 666 } 667 668 /* 669 * Check to see if the new vnode represents a special device 670 * for which we already have a vnode (either because of 671 * bdevvp() or because of a different vnode representing 672 * the same block device). If such an alias exists, deallocate 673 * the existing contents and return the aliased vnode. The 674 * caller is responsible for filling it with its new contents. 675 */ 676 struct vnode * 677 checkalias(nvp, nvp_rdev, mp) 678 register struct vnode *nvp; 679 dev_t nvp_rdev; 680 struct mount *mp; 681 { 682 register struct vnode *vp; 683 struct vnode **vpp; 684 685 if (nvp->v_type != VBLK && nvp->v_type != VCHR) 686 return (NULLVP); 687 688 vpp = &speclisth[SPECHASH(nvp_rdev)]; 689 loop: 690 for (vp = *vpp; vp; vp = vp->v_specnext) { 691 if (nvp_rdev != vp->v_rdev || nvp->v_type != vp->v_type) 692 continue; 693 /* 694 * Alias, but not in use, so flush it out. 695 */ 696 if (vp->v_usecount == 0) { 697 vgone(vp); 698 goto loop; 699 } 700 if (vget(vp, 1)) 701 goto loop; 702 break; 703 } 704 if (vp == NULL || vp->v_tag != VT_NON || vp->v_type != VBLK) { 705 MALLOC(nvp->v_specinfo, struct specinfo *, 706 sizeof(struct specinfo), M_VNODE, M_WAITOK); 707 nvp->v_rdev = nvp_rdev; 708 nvp->v_hashchain = vpp; 709 nvp->v_specnext = *vpp; 710 nvp->v_specflags = 0; 711 *vpp = nvp; 712 if (vp != NULL) { 713 nvp->v_flag |= VALIASED; 714 vp->v_flag |= VALIASED; 715 vput(vp); 716 } 717 return (NULLVP); 718 } 719 VOP_UNLOCK(vp); 720 vclean(vp, 0); 721 vp->v_op = nvp->v_op; 722 vp->v_tag = nvp->v_tag; 723 nvp->v_type = VNON; 724 insmntque(vp, mp); 725 return (vp); 726 } 727 728 /* 729 * Grab a particular vnode from the free list, increment its 730 * reference count and lock it. The vnode lock bit is set the 731 * vnode is being eliminated in vgone. The process is awakened 732 * when the transition is completed, and an error returned to 733 * indicate that the vnode is no longer usable (possibly having 734 * been changed to a new file system type). 735 */ 736 int 737 vget(vp, lockflag) 738 register struct vnode *vp; 739 int lockflag; 740 { 741 742 /* 743 * If the vnode is in the process of being cleaned out for 744 * another use, we wait for the cleaning to finish and then 745 * return failure. Cleaning is determined either by checking 746 * that the VXLOCK flag is set, or that the use count is 747 * zero with the back pointer set to show that it has been 748 * removed from the free list by getnewvnode. The VXLOCK 749 * flag may not have been set yet because vclean is blocked in 750 * the VOP_LOCK call waiting for the VOP_INACTIVE to complete. 751 */ 752 if ((vp->v_flag & VXLOCK) || 753 (vp->v_usecount == 0 && 754 vp->v_freelist.tqe_prev == (struct vnode **)0xdeadb)) { 755 vp->v_flag |= VXWANT; 756 tsleep((caddr_t)vp, PINOD, "vget", 0); 757 return (1); 758 } 759 if (vp->v_usecount == 0) 760 TAILQ_REMOVE(&vnode_free_list, vp, v_freelist); 761 vp->v_usecount++; 762 if (lockflag) 763 VOP_LOCK(vp); 764 return (0); 765 } 766 767 /* 768 * Vnode reference, just increment the count 769 */ 770 void 771 vref(vp) 772 struct vnode *vp; 773 { 774 775 if (vp->v_usecount <= 0) 776 panic("vref used where vget required"); 777 vp->v_usecount++; 778 } 779 780 /* 781 * vput(), just unlock and vrele() 782 */ 783 void 784 vput(vp) 785 register struct vnode *vp; 786 { 787 788 VOP_UNLOCK(vp); 789 vrele(vp); 790 } 791 792 /* 793 * Vnode release. 794 * If count drops to zero, call inactive routine and return to freelist. 795 */ 796 void 797 vrele(vp) 798 register struct vnode *vp; 799 { 800 801 #ifdef DIAGNOSTIC 802 if (vp == NULL) 803 panic("vrele: null vp"); 804 #endif 805 vp->v_usecount--; 806 if (vp->v_usecount > 0) 807 return; 808 #ifdef DIAGNOSTIC 809 if (vp->v_usecount != 0 || vp->v_writecount != 0) { 810 vprint("vrele: bad ref count", vp); 811 panic("vrele: ref cnt"); 812 } 813 #endif 814 /* 815 * insert at tail of LRU list 816 */ 817 TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist); 818 VOP_INACTIVE(vp); 819 } 820 821 /* 822 * Page or buffer structure gets a reference. 823 */ 824 void 825 vhold(vp) 826 register struct vnode *vp; 827 { 828 829 vp->v_holdcnt++; 830 } 831 832 /* 833 * Page or buffer structure frees a reference. 834 */ 835 void 836 holdrele(vp) 837 register struct vnode *vp; 838 { 839 840 if (vp->v_holdcnt <= 0) 841 panic("holdrele: holdcnt"); 842 vp->v_holdcnt--; 843 } 844 845 /* 846 * Remove any vnodes in the vnode table belonging to mount point mp. 847 * 848 * If MNT_NOFORCE is specified, there should not be any active ones, 849 * return error if any are found (nb: this is a user error, not a 850 * system error). If MNT_FORCE is specified, detach any active vnodes 851 * that are found. 852 */ 853 #ifdef DEBUG 854 int busyprt = 0; /* print out busy vnodes */ 855 struct ctldebug debug1 = { "busyprt", &busyprt }; 856 #endif 857 858 int 859 vflush(mp, skipvp, flags) 860 struct mount *mp; 861 struct vnode *skipvp; 862 int flags; 863 { 864 register struct vnode *vp, *nvp; 865 int busy = 0; 866 867 if ((mp->mnt_flag & MNT_MPBUSY) == 0) 868 panic("vflush: not busy"); 869 loop: 870 for (vp = mp->mnt_vnodelist.lh_first; vp; vp = nvp) { 871 if (vp->v_mount != mp) 872 goto loop; 873 nvp = vp->v_mntvnodes.le_next; 874 /* 875 * Skip over a selected vnode. 876 */ 877 if (vp == skipvp) 878 continue; 879 /* 880 * Skip over a vnodes marked VSYSTEM. 881 */ 882 if ((flags & SKIPSYSTEM) && (vp->v_flag & VSYSTEM)) 883 continue; 884 /* 885 * If WRITECLOSE is set, only flush out regular file 886 * vnodes open for writing. 887 */ 888 if ((flags & WRITECLOSE) && 889 (vp->v_writecount == 0 || vp->v_type != VREG)) 890 continue; 891 /* 892 * With v_usecount == 0, all we need to do is clear 893 * out the vnode data structures and we are done. 894 */ 895 if (vp->v_usecount == 0) { 896 vgone(vp); 897 continue; 898 } 899 /* 900 * If FORCECLOSE is set, forcibly close the vnode. 901 * For block or character devices, revert to an 902 * anonymous device. For all other files, just kill them. 903 */ 904 if (flags & FORCECLOSE) { 905 if (vp->v_type != VBLK && vp->v_type != VCHR) { 906 vgone(vp); 907 } else { 908 vclean(vp, 0); 909 vp->v_op = spec_vnodeop_p; 910 insmntque(vp, (struct mount *)0); 911 } 912 continue; 913 } 914 #ifdef DEBUG 915 if (busyprt) 916 vprint("vflush: busy vnode", vp); 917 #endif 918 busy++; 919 } 920 if (busy) 921 return (EBUSY); 922 return (0); 923 } 924 925 /* 926 * Disassociate the underlying file system from a vnode. 927 */ 928 void 929 vclean(vp, flags) 930 register struct vnode *vp; 931 int flags; 932 { 933 int active; 934 935 /* 936 * Check to see if the vnode is in use. 937 * If so we have to reference it before we clean it out 938 * so that its count cannot fall to zero and generate a 939 * race against ourselves to recycle it. 940 */ 941 if ((active = vp->v_usecount) != 0) 942 VREF(vp); 943 /* 944 * Even if the count is zero, the VOP_INACTIVE routine may still 945 * have the object locked while it cleans it out. The VOP_LOCK 946 * ensures that the VOP_INACTIVE routine is done with its work. 947 * For active vnodes, it ensures that no other activity can 948 * occur while the underlying object is being cleaned out. 949 */ 950 VOP_LOCK(vp); 951 /* 952 * Prevent the vnode from being recycled or 953 * brought into use while we clean it out. 954 */ 955 if (vp->v_flag & VXLOCK) 956 panic("vclean: deadlock"); 957 vp->v_flag |= VXLOCK; 958 /* 959 * Clean out any buffers associated with the vnode. 960 */ 961 if (flags & DOCLOSE) 962 vinvalbuf(vp, V_SAVE, NOCRED, NULL, 0, 0); 963 /* 964 * Any other processes trying to obtain this lock must first 965 * wait for VXLOCK to clear, then call the new lock operation. 966 */ 967 VOP_UNLOCK(vp); 968 /* 969 * If purging an active vnode, it must be closed and 970 * deactivated before being reclaimed. 971 */ 972 if (active) { 973 if (flags & DOCLOSE) 974 VOP_CLOSE(vp, FNONBLOCK, NOCRED, NULL); 975 VOP_INACTIVE(vp); 976 } 977 /* 978 * Reclaim the vnode. 979 */ 980 if (VOP_RECLAIM(vp)) 981 panic("vclean: cannot reclaim"); 982 if (active) 983 vrele(vp); 984 985 /* 986 * Done with purge, notify sleepers of the grim news. 987 */ 988 vp->v_op = dead_vnodeop_p; 989 vp->v_tag = VT_NON; 990 vp->v_flag &= ~VXLOCK; 991 if (vp->v_flag & VXWANT) { 992 vp->v_flag &= ~VXWANT; 993 wakeup((caddr_t)vp); 994 } 995 } 996 997 /* 998 * Eliminate all activity associated with the requested vnode 999 * and with all vnodes aliased to the requested vnode. 1000 */ 1001 void 1002 vgoneall(vp) 1003 register struct vnode *vp; 1004 { 1005 register struct vnode *vq; 1006 1007 if (vp->v_flag & VALIASED) { 1008 /* 1009 * If a vgone (or vclean) is already in progress, 1010 * wait until it is done and return. 1011 */ 1012 if (vp->v_flag & VXLOCK) { 1013 vp->v_flag |= VXWANT; 1014 tsleep((caddr_t)vp, PINOD, "vgoneall", 0); 1015 return; 1016 } 1017 /* 1018 * Ensure that vp will not be vgone'd while we 1019 * are eliminating its aliases. 1020 */ 1021 vp->v_flag |= VXLOCK; 1022 while (vp->v_flag & VALIASED) { 1023 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 1024 if (vq->v_rdev != vp->v_rdev || 1025 vq->v_type != vp->v_type || vp == vq) 1026 continue; 1027 vgone(vq); 1028 break; 1029 } 1030 } 1031 /* 1032 * Remove the lock so that vgone below will 1033 * really eliminate the vnode after which time 1034 * vgone will awaken any sleepers. 1035 */ 1036 vp->v_flag &= ~VXLOCK; 1037 } 1038 vgone(vp); 1039 } 1040 1041 /* 1042 * Eliminate all activity associated with a vnode 1043 * in preparation for reuse. 1044 */ 1045 void 1046 vgone(vp) 1047 register struct vnode *vp; 1048 { 1049 register struct vnode *vq; 1050 struct vnode *vx; 1051 1052 /* 1053 * If a vgone (or vclean) is already in progress, 1054 * wait until it is done and return. 1055 */ 1056 if (vp->v_flag & VXLOCK) { 1057 vp->v_flag |= VXWANT; 1058 tsleep((caddr_t)vp, PINOD, "vgone", 0); 1059 return; 1060 } 1061 /* 1062 * Clean out the filesystem specific data. 1063 */ 1064 vclean(vp, DOCLOSE); 1065 /* 1066 * Delete from old mount point vnode list, if on one. 1067 */ 1068 insmntque(vp, (struct mount *)0); 1069 /* 1070 * If special device, remove it from special device alias list. 1071 */ 1072 if (vp->v_type == VBLK || vp->v_type == VCHR) { 1073 if (*vp->v_hashchain == vp) { 1074 *vp->v_hashchain = vp->v_specnext; 1075 } else { 1076 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 1077 if (vq->v_specnext != vp) 1078 continue; 1079 vq->v_specnext = vp->v_specnext; 1080 break; 1081 } 1082 if (vq == NULL) 1083 panic("missing bdev"); 1084 } 1085 if (vp->v_flag & VALIASED) { 1086 vx = NULL; 1087 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 1088 if (vq->v_rdev != vp->v_rdev || 1089 vq->v_type != vp->v_type) 1090 continue; 1091 if (vx) 1092 break; 1093 vx = vq; 1094 } 1095 if (vx == NULL) 1096 panic("missing alias"); 1097 if (vq == NULL) 1098 vx->v_flag &= ~VALIASED; 1099 vp->v_flag &= ~VALIASED; 1100 } 1101 FREE(vp->v_specinfo, M_VNODE); 1102 vp->v_specinfo = NULL; 1103 } 1104 /* 1105 * If it is on the freelist and not already at the head, 1106 * move it to the head of the list. The test of the back 1107 * pointer and the reference count of zero is because 1108 * it will be removed from the free list by getnewvnode, 1109 * but will not have its reference count incremented until 1110 * after calling vgone. If the reference count were 1111 * incremented first, vgone would (incorrectly) try to 1112 * close the previous instance of the underlying object. 1113 * So, the back pointer is explicitly set to `0xdeadb' in 1114 * getnewvnode after removing it from the freelist to ensure 1115 * that we do not try to move it here. 1116 */ 1117 if (vp->v_usecount == 0 && 1118 vp->v_freelist.tqe_prev != (struct vnode **)0xdeadb && 1119 vnode_free_list.tqh_first != vp) { 1120 TAILQ_REMOVE(&vnode_free_list, vp, v_freelist); 1121 TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist); 1122 } 1123 vp->v_type = VBAD; 1124 } 1125 1126 /* 1127 * Lookup a vnode by device number. 1128 */ 1129 int 1130 vfinddev(dev, type, vpp) 1131 dev_t dev; 1132 enum vtype type; 1133 struct vnode **vpp; 1134 { 1135 register struct vnode *vp; 1136 1137 for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) { 1138 if (dev != vp->v_rdev || type != vp->v_type) 1139 continue; 1140 *vpp = vp; 1141 return (1); 1142 } 1143 return (0); 1144 } 1145 1146 /* 1147 * Calculate the total number of references to a special device. 1148 */ 1149 int 1150 vcount(vp) 1151 register struct vnode *vp; 1152 { 1153 register struct vnode *vq, *vnext; 1154 int count; 1155 1156 loop: 1157 if ((vp->v_flag & VALIASED) == 0) 1158 return (vp->v_usecount); 1159 for (count = 0, vq = *vp->v_hashchain; vq; vq = vnext) { 1160 vnext = vq->v_specnext; 1161 if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type) 1162 continue; 1163 /* 1164 * Alias, but not in use, so flush it out. 1165 */ 1166 if (vq->v_usecount == 0 && vq != vp) { 1167 vgone(vq); 1168 goto loop; 1169 } 1170 count += vq->v_usecount; 1171 } 1172 return (count); 1173 } 1174 1175 /* 1176 * Print out a description of a vnode. 1177 */ 1178 static char *typename[] = 1179 { "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" }; 1180 1181 void 1182 vprint(label, vp) 1183 char *label; 1184 register struct vnode *vp; 1185 { 1186 char buf[64]; 1187 1188 if (label != NULL) 1189 printf("%s: ", label); 1190 printf("type %s, usecount %d, writecount %d, refcount %d,", 1191 typename[vp->v_type], vp->v_usecount, vp->v_writecount, 1192 vp->v_holdcnt); 1193 buf[0] = '\0'; 1194 if (vp->v_flag & VROOT) 1195 strcat(buf, "|VROOT"); 1196 if (vp->v_flag & VTEXT) 1197 strcat(buf, "|VTEXT"); 1198 if (vp->v_flag & VSYSTEM) 1199 strcat(buf, "|VSYSTEM"); 1200 if (vp->v_flag & VXLOCK) 1201 strcat(buf, "|VXLOCK"); 1202 if (vp->v_flag & VXWANT) 1203 strcat(buf, "|VXWANT"); 1204 if (vp->v_flag & VBWAIT) 1205 strcat(buf, "|VBWAIT"); 1206 if (vp->v_flag & VALIASED) 1207 strcat(buf, "|VALIASED"); 1208 if (buf[0] != '\0') 1209 printf(" flags (%s)", &buf[1]); 1210 if (vp->v_data == NULL) { 1211 printf("\n"); 1212 } else { 1213 printf("\n\t"); 1214 VOP_PRINT(vp); 1215 } 1216 } 1217 1218 #ifdef DEBUG 1219 /* 1220 * List all of the locked vnodes in the system. 1221 * Called when debugging the kernel. 1222 */ 1223 void 1224 printlockedvnodes() 1225 { 1226 register struct mount *mp; 1227 register struct vnode *vp; 1228 1229 printf("Locked vnodes\n"); 1230 for (mp = mountlist.cqh_first; mp != (void *)&mountlist; 1231 mp = mp->mnt_list.cqe_next) { 1232 for (vp = mp->mnt_vnodelist.lh_first; 1233 vp != NULL; 1234 vp = vp->v_mntvnodes.le_next) 1235 if (VOP_ISLOCKED(vp)) 1236 vprint((char *)0, vp); 1237 } 1238 } 1239 #endif 1240 1241 int kinfo_vdebug = 1; 1242 int kinfo_vgetfailed; 1243 #define KINFO_VNODESLOP 10 1244 /* 1245 * Dump vnode list (via sysctl). 1246 * Copyout address of vnode followed by vnode. 1247 */ 1248 /* ARGSUSED */ 1249 int 1250 sysctl_vnode(where, sizep) 1251 char *where; 1252 size_t *sizep; 1253 { 1254 register struct mount *mp, *nmp; 1255 struct vnode *vp; 1256 register char *bp = where, *savebp; 1257 char *ewhere; 1258 int error; 1259 1260 #define VPTRSZ sizeof (struct vnode *) 1261 #define VNODESZ sizeof (struct vnode) 1262 if (where == NULL) { 1263 *sizep = (numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ); 1264 return (0); 1265 } 1266 ewhere = where + *sizep; 1267 1268 for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) { 1269 nmp = mp->mnt_list.cqe_next; 1270 if (vfs_busy(mp)) 1271 continue; 1272 savebp = bp; 1273 again: 1274 for (vp = mp->mnt_vnodelist.lh_first; 1275 vp != NULL; 1276 vp = vp->v_mntvnodes.le_next) { 1277 /* 1278 * Check that the vp is still associated with 1279 * this filesystem. RACE: could have been 1280 * recycled onto the same filesystem. 1281 */ 1282 if (vp->v_mount != mp) { 1283 if (kinfo_vdebug) 1284 printf("kinfo: vp changed\n"); 1285 bp = savebp; 1286 goto again; 1287 } 1288 if (bp + VPTRSZ + VNODESZ > ewhere) { 1289 *sizep = bp - where; 1290 return (ENOMEM); 1291 } 1292 if ((error = copyout((caddr_t)&vp, bp, VPTRSZ)) || 1293 (error = copyout((caddr_t)vp, bp + VPTRSZ, VNODESZ))) 1294 return (error); 1295 bp += VPTRSZ + VNODESZ; 1296 } 1297 vfs_unbusy(mp); 1298 } 1299 1300 *sizep = bp - where; 1301 return (0); 1302 } 1303 1304 /* 1305 * Check to see if a filesystem is mounted on a block device. 1306 */ 1307 int 1308 vfs_mountedon(vp) 1309 register struct vnode *vp; 1310 { 1311 register struct vnode *vq; 1312 1313 if (vp->v_specflags & SI_MOUNTEDON) 1314 return (EBUSY); 1315 if (vp->v_flag & VALIASED) { 1316 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { 1317 if (vq->v_rdev != vp->v_rdev || 1318 vq->v_type != vp->v_type) 1319 continue; 1320 if (vq->v_specflags & SI_MOUNTEDON) 1321 return (EBUSY); 1322 } 1323 } 1324 return (0); 1325 } 1326 1327 /* 1328 * Build hash lists of net addresses and hang them off the mount point. 1329 * Called by ufs_mount() to set up the lists of export addresses. 1330 */ 1331 static int 1332 vfs_hang_addrlist(mp, nep, argp) 1333 struct mount *mp; 1334 struct netexport *nep; 1335 struct export_args *argp; 1336 { 1337 register struct netcred *np; 1338 register struct radix_node_head *rnh; 1339 register int i; 1340 struct radix_node *rn; 1341 struct sockaddr *saddr, *smask = 0; 1342 struct domain *dom; 1343 int error; 1344 1345 if (argp->ex_addrlen == 0) { 1346 if (mp->mnt_flag & MNT_DEFEXPORTED) 1347 return (EPERM); 1348 np = &nep->ne_defexported; 1349 np->netc_exflags = argp->ex_flags; 1350 np->netc_anon = argp->ex_anon; 1351 np->netc_anon.cr_ref = 1; 1352 mp->mnt_flag |= MNT_DEFEXPORTED; 1353 return (0); 1354 } 1355 i = sizeof(struct netcred) + argp->ex_addrlen + argp->ex_masklen; 1356 np = (struct netcred *)malloc(i, M_NETADDR, M_WAITOK); 1357 bzero((caddr_t)np, i); 1358 saddr = (struct sockaddr *)(np + 1); 1359 error = copyin(argp->ex_addr, (caddr_t)saddr, argp->ex_addrlen); 1360 if (error) 1361 goto out; 1362 if (saddr->sa_len > argp->ex_addrlen) 1363 saddr->sa_len = argp->ex_addrlen; 1364 if (argp->ex_masklen) { 1365 smask = (struct sockaddr *)((caddr_t)saddr + argp->ex_addrlen); 1366 error = copyin(argp->ex_addr, (caddr_t)smask, argp->ex_masklen); 1367 if (error) 1368 goto out; 1369 if (smask->sa_len > argp->ex_masklen) 1370 smask->sa_len = argp->ex_masklen; 1371 } 1372 i = saddr->sa_family; 1373 if ((rnh = nep->ne_rtable[i]) == 0) { 1374 /* 1375 * Seems silly to initialize every AF when most are not 1376 * used, do so on demand here 1377 */ 1378 for (dom = domains; dom; dom = dom->dom_next) 1379 if (dom->dom_family == i && dom->dom_rtattach) { 1380 dom->dom_rtattach((void **)&nep->ne_rtable[i], 1381 dom->dom_rtoffset); 1382 break; 1383 } 1384 if ((rnh = nep->ne_rtable[i]) == 0) { 1385 error = ENOBUFS; 1386 goto out; 1387 } 1388 } 1389 rn = (*rnh->rnh_addaddr)((caddr_t)saddr, (caddr_t)smask, rnh, 1390 np->netc_rnodes); 1391 if (rn == 0 || np != (struct netcred *)rn) { /* already exists */ 1392 error = EPERM; 1393 goto out; 1394 } 1395 np->netc_exflags = argp->ex_flags; 1396 np->netc_anon = argp->ex_anon; 1397 np->netc_anon.cr_ref = 1; 1398 return (0); 1399 out: 1400 free(np, M_NETADDR); 1401 return (error); 1402 } 1403 1404 /* ARGSUSED */ 1405 static int 1406 vfs_free_netcred(rn, w) 1407 struct radix_node *rn; 1408 void *w; 1409 { 1410 register struct radix_node_head *rnh = (struct radix_node_head *)w; 1411 1412 (*rnh->rnh_deladdr)(rn->rn_key, rn->rn_mask, rnh); 1413 free((caddr_t)rn, M_NETADDR); 1414 return (0); 1415 } 1416 1417 /* 1418 * Free the net address hash lists that are hanging off the mount points. 1419 */ 1420 static void 1421 vfs_free_addrlist(nep) 1422 struct netexport *nep; 1423 { 1424 register int i; 1425 register struct radix_node_head *rnh; 1426 1427 for (i = 0; i <= AF_MAX; i++) 1428 if ((rnh = nep->ne_rtable[i]) != NULL) { 1429 (*rnh->rnh_walktree)(rnh, vfs_free_netcred, rnh); 1430 free((caddr_t)rnh, M_RTABLE); 1431 nep->ne_rtable[i] = 0; 1432 } 1433 } 1434 1435 int 1436 vfs_export(mp, nep, argp) 1437 struct mount *mp; 1438 struct netexport *nep; 1439 struct export_args *argp; 1440 { 1441 int error; 1442 1443 if (argp->ex_flags & MNT_DELEXPORT) { 1444 vfs_free_addrlist(nep); 1445 mp->mnt_flag &= ~(MNT_EXPORTED | MNT_DEFEXPORTED); 1446 } 1447 if (argp->ex_flags & MNT_EXPORTED) { 1448 if ((error = vfs_hang_addrlist(mp, nep, argp)) != 0) 1449 return (error); 1450 mp->mnt_flag |= MNT_EXPORTED; 1451 } 1452 return (0); 1453 } 1454 1455 struct netcred * 1456 vfs_export_lookup(mp, nep, nam) 1457 register struct mount *mp; 1458 struct netexport *nep; 1459 struct mbuf *nam; 1460 { 1461 register struct netcred *np; 1462 register struct radix_node_head *rnh; 1463 struct sockaddr *saddr; 1464 1465 np = NULL; 1466 if (mp->mnt_flag & MNT_EXPORTED) { 1467 /* 1468 * Lookup in the export list first. 1469 */ 1470 if (nam != NULL) { 1471 saddr = mtod(nam, struct sockaddr *); 1472 rnh = nep->ne_rtable[saddr->sa_family]; 1473 if (rnh != NULL) { 1474 np = (struct netcred *) 1475 (*rnh->rnh_matchaddr)((caddr_t)saddr, 1476 rnh); 1477 if (np && np->netc_rnodes->rn_flags & RNF_ROOT) 1478 np = NULL; 1479 } 1480 } 1481 /* 1482 * If no address match, use the default if it exists. 1483 */ 1484 if (np == NULL && mp->mnt_flag & MNT_DEFEXPORTED) 1485 np = &nep->ne_defexported; 1486 } 1487 return (np); 1488 } 1489 1490 /* 1491 * Do the usual access checking. 1492 * file_mode, uid and gid are from the vnode in question, 1493 * while acc_mode and cred are from the VOP_ACCESS parameter list 1494 */ 1495 int 1496 vaccess(file_mode, uid, gid, acc_mode, cred) 1497 mode_t file_mode; 1498 uid_t uid; 1499 gid_t gid; 1500 mode_t acc_mode; 1501 struct ucred *cred; 1502 { 1503 mode_t mask; 1504 1505 /* User id 0 always gets access. */ 1506 if (cred->cr_uid == 0) 1507 return 0; 1508 1509 mask = 0; 1510 1511 /* Otherwise, check the owner. */ 1512 if (cred->cr_uid == uid) { 1513 if (acc_mode & VEXEC) 1514 mask |= S_IXUSR; 1515 if (acc_mode & VREAD) 1516 mask |= S_IRUSR; 1517 if (acc_mode & VWRITE) 1518 mask |= S_IWUSR; 1519 return (file_mode & mask) == mask ? 0 : EACCES; 1520 } 1521 1522 /* Otherwise, check the groups. */ 1523 if (cred->cr_gid == gid || groupmember(gid, cred)) { 1524 if (acc_mode & VEXEC) 1525 mask |= S_IXGRP; 1526 if (acc_mode & VREAD) 1527 mask |= S_IRGRP; 1528 if (acc_mode & VWRITE) 1529 mask |= S_IWGRP; 1530 return (file_mode & mask) == mask ? 0 : EACCES; 1531 } 1532 1533 /* Otherwise, check everyone else. */ 1534 if (acc_mode & VEXEC) 1535 mask |= S_IXOTH; 1536 if (acc_mode & VREAD) 1537 mask |= S_IROTH; 1538 if (acc_mode & VWRITE) 1539 mask |= S_IWOTH; 1540 return (file_mode & mask) == mask ? 0 : EACCES; 1541 } 1542 1543 /* 1544 * Unmount all file systems. 1545 * We traverse the list in reverse order under the assumption that doing so 1546 * will avoid needing to worry about dependencies. 1547 */ 1548 void 1549 vfs_unmountall() 1550 { 1551 register struct mount *mp, *nmp; 1552 int allerror, error; 1553 1554 for (allerror = 0, 1555 mp = mountlist.cqh_last; mp != (void *)&mountlist; mp = nmp) { 1556 nmp = mp->mnt_list.cqe_prev; 1557 if ((error = dounmount(mp, MNT_FORCE, &proc0)) != 0) { 1558 printf("unmount of %s failed with error %d\n", 1559 mp->mnt_stat.f_mntonname, error); 1560 allerror = 1; 1561 } 1562 } 1563 if (allerror) 1564 printf("WARNING: some file systems would not unmount\n"); 1565 } 1566 1567 /* 1568 * Sync and unmount file systems before shutting down. 1569 */ 1570 void 1571 vfs_shutdown() 1572 { 1573 register struct buf *bp; 1574 int iter, nbusy; 1575 1576 /* XXX Should suspend scheduling. */ 1577 (void) spl0(); 1578 1579 printf("syncing disks... "); 1580 1581 if (panicstr == 0) { 1582 /* Release inodes held by texts before update. */ 1583 vnode_pager_umount(NULL); 1584 #ifdef notdef 1585 vnshutdown(); 1586 #endif 1587 1588 /* Sync before unmount, in case we hang on something. */ 1589 sys_sync(&proc0, (void *)0, (register_t *)0); 1590 1591 /* Unmount file systems. */ 1592 vfs_unmountall(); 1593 } 1594 1595 /* Sync again after unmount, just in case. */ 1596 sys_sync(&proc0, (void *)0, (register_t *)0); 1597 1598 /* Wait for sync to finish. */ 1599 for (iter = 0; iter < 20; iter++) { 1600 nbusy = 0; 1601 for (bp = &buf[nbuf]; --bp >= buf; ) 1602 if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY) 1603 nbusy++; 1604 if (nbusy == 0) 1605 break; 1606 printf("%d ", nbusy); 1607 DELAY(40000 * iter); 1608 } 1609 if (nbusy) 1610 printf("giving up\n"); 1611 else 1612 printf("done\n"); 1613 } 1614