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