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