1 /* $NetBSD: vfs_subr.c,v 1.504 2026/08/06 22:28:23 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008, 2019, 2020 5 * The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center, by Charles M. Hannum, by Andrew Doran, 11 * by Marshall Kirk McKusick and Greg Ganger at the University of Michigan. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 /* 36 * Copyright (c) 1989, 1993 37 * The Regents of the University of California. All rights reserved. 38 * (c) UNIX System Laboratories, Inc. 39 * All or some portions of this file are derived from material licensed 40 * to the University of California by American Telephone and Telegraph 41 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 42 * the permission of UNIX System Laboratories, Inc. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. Neither the name of the University nor the names of its contributors 53 * may be used to endorse or promote products derived from this software 54 * without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 * SUCH DAMAGE. 67 * 68 * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 69 */ 70 71 #include <sys/cdefs.h> 72 __KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.504 2026/08/06 22:28:23 riastradh Exp $"); 73 74 #ifdef _KERNEL_OPT 75 #include "opt_compat_43.h" 76 #include "opt_compat_netbsd.h" 77 #include "opt_ddb.h" 78 #endif 79 80 #include <sys/param.h> 81 #include <sys/types.h> 82 83 #include <sys/buf.h> 84 #include <sys/conf.h> 85 #include <sys/dirent.h> 86 #include <sys/errno.h> 87 #include <sys/filedesc.h> 88 #include <sys/fstrans.h> 89 #include <sys/kauth.h> 90 #include <sys/kernel.h> 91 #include <sys/kmem.h> 92 #include <sys/module.h> 93 #include <sys/mount.h> 94 #include <sys/namei.h> 95 #include <sys/sdt.h> 96 #include <sys/stat.h> 97 #include <sys/syscallargs.h> 98 #include <sys/sysctl.h> 99 #include <sys/systm.h> 100 #include <sys/vnode_impl.h> 101 102 #include <miscfs/deadfs/deadfs.h> 103 #include <miscfs/genfs/genfs.h> 104 #include <miscfs/specfs/specdev.h> 105 106 #include <uvm/uvm_ddb.h> 107 108 SDT_PROBE_DEFINE3(vfs, syncer, worklist, vnode__add, 109 "struct vnode *"/*vp*/, 110 "int"/*delayx*/, 111 "int"/*slot*/); 112 SDT_PROBE_DEFINE4(vfs, syncer, worklist, vnode__update, 113 "struct vnode *"/*vp*/, 114 "int"/*delayx*/, 115 "int"/*oslot*/, 116 "int"/*nslot*/); 117 SDT_PROBE_DEFINE1(vfs, syncer, worklist, vnode__remove, 118 "struct vnode *"/*vp*/); 119 120 SDT_PROBE_DEFINE3(vfs, syncer, worklist, mount__add, 121 "struct mount *"/*mp*/, 122 "int"/*vdelay*/, 123 "int"/*slot*/); 124 SDT_PROBE_DEFINE4(vfs, syncer, worklist, mount__update, 125 "struct mount *"/*vp*/, 126 "int"/*vdelay*/, 127 "int"/*oslot*/, 128 "int"/*nslot*/); 129 SDT_PROBE_DEFINE1(vfs, syncer, worklist, mount__remove, 130 "struct mount *"/*mp*/); 131 132 SDT_PROBE_DEFINE1(vfs, syncer, sync, start, 133 "int"/*starttime*/); 134 SDT_PROBE_DEFINE1(vfs, syncer, sync, mount__start, 135 "struct mount *"/*mp*/); 136 SDT_PROBE_DEFINE2(vfs, syncer, sync, mount__done, 137 "struct mount *"/*mp*/, 138 "int"/*error*/); 139 SDT_PROBE_DEFINE1(vfs, syncer, sync, mount__skip, 140 "struct mount *"/*mp*/); 141 SDT_PROBE_DEFINE1(vfs, syncer, sync, vnode__start, 142 "struct vnode *"/*vp*/); 143 SDT_PROBE_DEFINE2(vfs, syncer, sync, vnode__done, 144 "struct vnode *"/*vp*/, 145 "int"/*error*/); 146 SDT_PROBE_DEFINE2(vfs, syncer, sync, vnode__fail__lock, 147 "struct vnode *"/*vp*/, 148 "int"/*error*/); 149 SDT_PROBE_DEFINE2(vfs, syncer, sync, vnode__fail__vget, 150 "struct vnode *"/*vp*/, 151 "int"/*error*/); 152 SDT_PROBE_DEFINE2(vfs, syncer, sync, done, 153 "int"/*starttime*/, 154 "int"/*endtime*/); 155 156 const enum vtype iftovt_tab[16] = { 157 VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON, 158 VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD, 159 }; 160 const int vttoif_tab[9] = { 161 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, 162 S_IFSOCK, S_IFIFO, S_IFMT, 163 }; 164 165 /* 166 * Insq/Remq for the vnode usage lists. 167 */ 168 #define bufinsvn(bp, dp) LIST_INSERT_HEAD(dp, bp, b_vnbufs) 169 #define bufremvn(bp) { \ 170 LIST_REMOVE(bp, b_vnbufs); \ 171 (bp)->b_vnbufs.le_next = NOLIST; \ 172 } 173 174 int doforce = 1; /* 1 => permit forcible unmounting */ 175 176 /* 177 * Local declarations. 178 */ 179 180 static void vn_initialize_syncerd(void); 181 182 /* 183 * Initialize the vnode management data structures. 184 */ 185 void 186 vntblinit(void) 187 { 188 189 vn_initialize_syncerd(); 190 vfs_mount_sysinit(); 191 vfs_vnode_sysinit(); 192 } 193 194 /* 195 * Flush out and invalidate all buffers associated with a vnode. 196 * Called with the underlying vnode locked, which should prevent new dirty 197 * buffers from being queued. 198 */ 199 int 200 vinvalbuf(struct vnode *vp, int flags, kauth_cred_t cred, struct lwp *l, 201 bool catch_p, int slptimeo) 202 { 203 struct buf *bp, *nbp; 204 int error; 205 int flushflags = PGO_ALLPAGES | PGO_FREE | PGO_SYNCIO | 206 (flags & V_SAVE ? PGO_CLEANIT | PGO_RECLAIM : 0); 207 208 /* XXXUBC this doesn't look at flags or slp* */ 209 rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); 210 error = VOP_PUTPAGES(vp, 0, 0, flushflags); 211 if (error) { 212 return error; 213 } 214 215 if (flags & V_SAVE) { 216 error = VOP_FSYNC(vp, cred, FSYNC_WAIT|FSYNC_RECLAIM, 0, 0); 217 if (error) 218 return error; 219 KASSERT(LIST_EMPTY(&vp->v_dirtyblkhd)); 220 } 221 222 mutex_enter(&bufcache_lock); 223 restart: 224 for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { 225 KASSERT(bp->b_vp == vp); 226 nbp = LIST_NEXT(bp, b_vnbufs); 227 error = bbusy(bp, catch_p, slptimeo, NULL); 228 if (error != 0) { 229 if (error == EPASSTHROUGH) 230 goto restart; 231 mutex_exit(&bufcache_lock); 232 return error; 233 } 234 brelsel(bp, BC_INVAL | BC_VFLUSH); 235 } 236 237 for (bp = LIST_FIRST(&vp->v_cleanblkhd); bp; bp = nbp) { 238 KASSERT(bp->b_vp == vp); 239 nbp = LIST_NEXT(bp, b_vnbufs); 240 error = bbusy(bp, catch_p, slptimeo, NULL); 241 if (error != 0) { 242 if (error == EPASSTHROUGH) 243 goto restart; 244 mutex_exit(&bufcache_lock); 245 return error; 246 } 247 /* 248 * XXX Since there are no node locks for NFS, I believe 249 * there is a slight chance that a delayed write will 250 * occur while sleeping just above, so check for it. 251 */ 252 if ((bp->b_oflags & BO_DELWRI) && (flags & V_SAVE)) { 253 #ifdef DEBUG 254 printf("buffer still DELWRI\n"); 255 #endif 256 bp->b_cflags |= BC_BUSY | BC_VFLUSH; 257 mutex_exit(&bufcache_lock); 258 VOP_BWRITE(bp->b_vp, bp); 259 mutex_enter(&bufcache_lock); 260 goto restart; 261 } 262 brelsel(bp, BC_INVAL | BC_VFLUSH); 263 } 264 265 #ifdef DIAGNOSTIC 266 if (!LIST_EMPTY(&vp->v_cleanblkhd) || !LIST_EMPTY(&vp->v_dirtyblkhd)) 267 panic("vinvalbuf: flush failed, vp %p", vp); 268 #endif 269 270 mutex_exit(&bufcache_lock); 271 272 return 0; 273 } 274 275 /* 276 * Destroy any in core blocks past the truncation length. 277 * Called with the underlying vnode locked, which should prevent new dirty 278 * buffers from being queued. 279 */ 280 int 281 vtruncbuf(struct vnode *vp, daddr_t lbn, bool catch_p, int slptimeo) 282 { 283 struct buf *bp, *nbp; 284 int error; 285 voff_t off; 286 287 off = round_page((voff_t)lbn << vp->v_mount->mnt_fs_bshift); 288 rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); 289 error = VOP_PUTPAGES(vp, off, 0, PGO_FREE | PGO_SYNCIO); 290 if (error) { 291 return error; 292 } 293 294 mutex_enter(&bufcache_lock); 295 restart: 296 for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { 297 KASSERT(bp->b_vp == vp); 298 nbp = LIST_NEXT(bp, b_vnbufs); 299 if (bp->b_lblkno < lbn) 300 continue; 301 error = bbusy(bp, catch_p, slptimeo, NULL); 302 if (error != 0) { 303 if (error == EPASSTHROUGH) 304 goto restart; 305 mutex_exit(&bufcache_lock); 306 return error; 307 } 308 brelsel(bp, BC_INVAL | BC_VFLUSH); 309 } 310 311 for (bp = LIST_FIRST(&vp->v_cleanblkhd); bp; bp = nbp) { 312 KASSERT(bp->b_vp == vp); 313 nbp = LIST_NEXT(bp, b_vnbufs); 314 if (bp->b_lblkno < lbn) 315 continue; 316 error = bbusy(bp, catch_p, slptimeo, NULL); 317 if (error != 0) { 318 if (error == EPASSTHROUGH) 319 goto restart; 320 mutex_exit(&bufcache_lock); 321 return error; 322 } 323 brelsel(bp, BC_INVAL | BC_VFLUSH); 324 } 325 mutex_exit(&bufcache_lock); 326 327 return 0; 328 } 329 330 /* 331 * Flush all dirty buffers from a vnode. 332 * Called with the underlying vnode locked, which should prevent new dirty 333 * buffers from being queued. 334 */ 335 int 336 vflushbuf(struct vnode *vp, int flags) 337 { 338 struct buf *bp, *nbp; 339 int error, pflags; 340 bool dirty, sync; 341 #ifdef DEBUG 342 bool warned = false; 343 #endif 344 345 sync = (flags & FSYNC_WAIT) != 0; 346 pflags = PGO_CLEANIT | PGO_ALLPAGES | 347 (sync ? PGO_SYNCIO : 0) | 348 ((flags & FSYNC_LAZY) ? PGO_LAZY : 0); 349 rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); 350 (void) VOP_PUTPAGES(vp, 0, 0, pflags); 351 352 loop: 353 mutex_enter(&bufcache_lock); 354 for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { 355 KASSERT(bp->b_vp == vp); 356 nbp = LIST_NEXT(bp, b_vnbufs); 357 if ((bp->b_cflags & BC_BUSY)) 358 continue; 359 if ((bp->b_oflags & BO_DELWRI) == 0) 360 panic("vflushbuf: not dirty, bp %p", bp); 361 bp->b_cflags |= BC_BUSY | BC_VFLUSH; 362 mutex_exit(&bufcache_lock); 363 /* 364 * Wait for I/O associated with indirect blocks to complete, 365 * since there is no way to quickly wait for them below. 366 */ 367 if (bp->b_vp == vp || !sync) 368 (void) bawrite(bp); 369 else { 370 error = bwrite(bp); 371 if (error) 372 return error; 373 } 374 goto loop; 375 } 376 mutex_exit(&bufcache_lock); 377 378 if (!sync) 379 return 0; 380 381 mutex_enter(vp->v_interlock); 382 while (vp->v_numoutput != 0) 383 cv_wait(&vp->v_cv, vp->v_interlock); 384 dirty = !LIST_EMPTY(&vp->v_dirtyblkhd); 385 mutex_exit(vp->v_interlock); 386 387 if (dirty) { 388 #ifdef DEBUG 389 if (!warned) { 390 static struct timeval vflushbuf_warntime; 391 const struct timeval interval = {60,0}; 392 393 mutex_enter(&bufcache_lock); 394 if (ratecheck(&vflushbuf_warntime, &interval)) 395 vprint("vflushbuf: dirty", vp); 396 mutex_exit(&bufcache_lock); 397 warned = true; 398 } 399 #endif 400 goto loop; 401 } 402 403 return 0; 404 } 405 406 /* 407 * Create a vnode for a block device. 408 * Used for root filesystem and swap areas. 409 * Also used for memory file system special devices. 410 */ 411 int 412 bdevvp(dev_t dev, vnode_t **vpp) 413 { 414 struct vattr va; 415 416 vattr_null(&va); 417 va.va_type = VBLK; 418 va.va_rdev = dev; 419 420 return vcache_new(dead_rootmount, NULL, &va, NOCRED, NULL, vpp); 421 } 422 423 /* 424 * Create a vnode for a character device. 425 * Used for kernfs and some console handling. 426 */ 427 int 428 cdevvp(dev_t dev, vnode_t **vpp) 429 { 430 struct vattr va; 431 432 vattr_null(&va); 433 va.va_type = VCHR; 434 va.va_rdev = dev; 435 436 return vcache_new(dead_rootmount, NULL, &va, NOCRED, NULL, vpp); 437 } 438 439 /* 440 * Associate a buffer with a vnode. There must already be a hold on 441 * the vnode. 442 */ 443 void 444 bgetvp(struct vnode *vp, struct buf *bp) 445 { 446 447 KASSERT(bp->b_vp == NULL); 448 KASSERT(bp->b_objlock == &buffer_lock); 449 KASSERT(mutex_owned(vp->v_interlock)); 450 KASSERT(mutex_owned(&bufcache_lock)); 451 KASSERT((bp->b_cflags & BC_BUSY) != 0); 452 KASSERT(!cv_has_waiters(&bp->b_done)); 453 454 vholdl(vp); 455 bp->b_vp = vp; 456 if (vp->v_type == VBLK || vp->v_type == VCHR) 457 bp->b_dev = vp->v_rdev; 458 else 459 bp->b_dev = NODEV; 460 461 /* 462 * Insert onto list for new vnode. 463 */ 464 bufinsvn(bp, &vp->v_cleanblkhd); 465 bp->b_objlock = vp->v_interlock; 466 } 467 468 /* 469 * Disassociate a buffer from a vnode. 470 */ 471 void 472 brelvp(struct buf *bp) 473 { 474 struct vnode *vp = bp->b_vp; 475 476 KASSERT(vp != NULL); 477 KASSERT(bp->b_objlock == vp->v_interlock); 478 KASSERT(mutex_owned(vp->v_interlock)); 479 KASSERT(mutex_owned(&bufcache_lock)); 480 KASSERT((bp->b_cflags & BC_BUSY) != 0); 481 KASSERT(!cv_has_waiters(&bp->b_done)); 482 483 /* 484 * Delete from old vnode list, if on one. 485 */ 486 if (LIST_NEXT(bp, b_vnbufs) != NOLIST) 487 bufremvn(bp); 488 489 if ((vp->v_iflag & (VI_ONWORKLST | VI_PAGES)) == VI_ONWORKLST && 490 LIST_FIRST(&vp->v_dirtyblkhd) == NULL) 491 vn_syncer_remove_from_worklist(vp); 492 493 bp->b_objlock = &buffer_lock; 494 bp->b_vp = NULL; 495 holdrelel(vp); 496 } 497 498 /* 499 * Reassign a buffer from one vnode list to another. 500 * The list reassignment must be within the same vnode. 501 * Used to assign file specific control information 502 * (indirect blocks) to the list to which they belong. 503 */ 504 void 505 reassignbuf(struct buf *bp, struct vnode *vp) 506 { 507 struct buflists *listheadp; 508 int delayx; 509 510 KASSERT(mutex_owned(&bufcache_lock)); 511 KASSERT(bp->b_objlock == vp->v_interlock); 512 KASSERT(mutex_owned(vp->v_interlock)); 513 KASSERT((bp->b_cflags & BC_BUSY) != 0); 514 515 /* 516 * Delete from old vnode list, if on one. 517 */ 518 if (LIST_NEXT(bp, b_vnbufs) != NOLIST) 519 bufremvn(bp); 520 521 /* 522 * If dirty, put on list of dirty buffers; 523 * otherwise insert onto list of clean buffers. 524 */ 525 if ((bp->b_oflags & BO_DELWRI) == 0) { 526 listheadp = &vp->v_cleanblkhd; 527 if ((vp->v_iflag & (VI_ONWORKLST | VI_PAGES)) == 528 VI_ONWORKLST && 529 LIST_FIRST(&vp->v_dirtyblkhd) == NULL) 530 vn_syncer_remove_from_worklist(vp); 531 } else { 532 listheadp = &vp->v_dirtyblkhd; 533 if ((vp->v_iflag & VI_ONWORKLST) == 0) { 534 switch (vp->v_type) { 535 case VDIR: 536 delayx = dirdelay; 537 break; 538 case VBLK: 539 if (spec_node_getmountedfs(vp) != NULL) { 540 delayx = metadelay; 541 break; 542 } 543 /* fall through */ 544 default: 545 delayx = filedelay; 546 break; 547 } 548 if (!vp->v_mount || 549 (vp->v_mount->mnt_flag & MNT_ASYNC) == 0) 550 vn_syncer_add_to_worklist(vp, delayx); 551 } 552 } 553 bufinsvn(bp, listheadp); 554 } 555 556 /* 557 * Lookup a vnode by device number and return it referenced. 558 */ 559 int 560 vfinddev(dev_t dev, enum vtype type, vnode_t **vpp) 561 { 562 563 return (spec_node_lookup_by_dev(type, dev, VDEAD_NOWAIT, vpp) == 0); 564 } 565 566 /* 567 * Revoke all the vnodes corresponding to the specified minor number 568 * range (endpoints inclusive) of the specified major. 569 */ 570 void 571 vdevgone(int maj, int minl, int minh, enum vtype type) 572 { 573 vnode_t *vp; 574 dev_t dev; 575 int mn; 576 577 for (mn = minl; mn <= minh; mn++) { 578 dev = makedev(maj, mn); 579 /* 580 * Notify anyone trying to get at this device that it 581 * has been detached, and then revoke it. 582 */ 583 switch (type) { 584 case VBLK: 585 bdev_detached(dev); 586 break; 587 case VCHR: 588 cdev_detached(dev); 589 break; 590 default: 591 panic("invalid specnode type: %d", type); 592 } 593 /* 594 * Passing 0 as flags, instead of VDEAD_NOWAIT, means 595 * spec_node_lookup_by_dev will wait for vnodes it 596 * finds concurrently being revoked before returning. 597 */ 598 while (spec_node_lookup_by_dev(type, dev, 0, &vp) == 0) { 599 VOP_REVOKE(vp, REVOKEALL); 600 vrele(vp); 601 } 602 } 603 } 604 605 /* 606 * The filesystem synchronizer mechanism - syncer. 607 * 608 * It is useful to delay writes of file data and filesystem metadata for 609 * a certain amount of time so that quickly created and deleted files need 610 * not waste disk bandwidth being created and removed. To implement this, 611 * vnodes are appended to a "workitem" queue. 612 * 613 * Most pending metadata should not wait for more than ten seconds. Thus, 614 * mounted on block devices are delayed only about a half the time that file 615 * data is delayed. Similarly, directory updates are more critical, so are 616 * only delayed about a third the time that file data is delayed. 617 * 618 * There are SYNCER_MAXDELAY queues that are processed in a round-robin 619 * manner at a rate of one each second (driven off the filesystem syner 620 * thread). The syncer_delayno variable indicates the next queue that is 621 * to be processed. Items that need to be processed soon are placed in 622 * this queue: 623 * 624 * syncer_workitem_pending[syncer_delayno] 625 * 626 * A delay of e.g. fifteen seconds is done by placing the request fifteen 627 * entries later in the queue: 628 * 629 * syncer_workitem_pending[(syncer_delayno + 15) & syncer_mask] 630 * 631 * Flag VI_ONWORKLST indicates that vnode is added into the queue. 632 */ 633 634 #define SYNCER_MAXDELAY 32 635 636 typedef TAILQ_HEAD(synclist, vnode_impl) synclist_t; 637 638 static void vn_syncer_add1(struct vnode *, int); 639 static void sysctl_vfs_syncfs_setup(struct sysctllog **); 640 641 /* 642 * Defines and variables for the syncer process. 643 */ 644 int syncer_maxdelay = SYNCER_MAXDELAY; /* maximum delay time */ 645 time_t syncdelay = 30; /* max time to delay syncing data */ 646 time_t filedelay = 30; /* time to delay syncing files */ 647 time_t dirdelay = 15; /* time to delay syncing directories */ 648 time_t metadelay = 10; /* time to delay syncing metadata */ 649 time_t lockdelay = 1; /* time to delay if locking fails */ 650 651 static kmutex_t syncer_data_lock; /* short term lock on data structs */ 652 653 static int syncer_delayno = 0; 654 static long syncer_last; 655 static synclist_t * syncer_workitem_pending; 656 657 static void 658 vn_initialize_syncerd(void) 659 { 660 int i; 661 662 syncer_last = SYNCER_MAXDELAY + 2; 663 664 sysctl_vfs_syncfs_setup(NULL); 665 666 syncer_workitem_pending = 667 kmem_alloc(syncer_last * sizeof (struct synclist), KM_SLEEP); 668 669 for (i = 0; i < syncer_last; i++) 670 TAILQ_INIT(&syncer_workitem_pending[i]); 671 672 mutex_init(&syncer_data_lock, MUTEX_DEFAULT, IPL_NONE); 673 } 674 675 /* 676 * Return delay factor appropriate for the given file system. For 677 * WAPBL we use the sync vnode to burst out metadata updates: sync 678 * those file systems more frequently. 679 */ 680 static inline int 681 sync_delay(struct mount *mp) 682 { 683 684 return mp->mnt_wapbl != NULL ? metadelay : syncdelay; 685 } 686 687 /* 688 * Compute the next slot index from delay. 689 */ 690 static inline int 691 sync_delay_slot(int delayx) 692 { 693 694 if (delayx > syncer_maxdelay - 2) 695 delayx = syncer_maxdelay - 2; 696 return (syncer_delayno + delayx) % syncer_last; 697 } 698 699 /* 700 * Add an item to the syncer work queue. 701 */ 702 static void 703 vn_syncer_add1(struct vnode *vp, int delayx) 704 { 705 synclist_t *slp; 706 vnode_impl_t *vip = VNODE_TO_VIMPL(vp); 707 708 KASSERT(mutex_owned(&syncer_data_lock)); 709 710 if (vp->v_iflag & VI_ONWORKLST) { 711 /* 712 * Remove in order to adjust the position of the vnode. 713 * Note: called from sched_sync(), which will not hold 714 * interlock, therefore we cannot modify v_iflag here. 715 */ 716 slp = &syncer_workitem_pending[vip->vi_synclist_slot]; 717 TAILQ_REMOVE(slp, vip, vi_synclist); 718 } else { 719 KASSERT(mutex_owned(vp->v_interlock)); 720 vp->v_iflag |= VI_ONWORKLST; 721 } 722 723 vip->vi_synclist_slot = sync_delay_slot(delayx); 724 725 slp = &syncer_workitem_pending[vip->vi_synclist_slot]; 726 TAILQ_INSERT_TAIL(slp, vip, vi_synclist); 727 } 728 729 void 730 vn_syncer_add_to_worklist(struct vnode *vp, int delayx) 731 { 732 vnode_impl_t *vip = VNODE_TO_VIMPL(vp); 733 734 KASSERT(mutex_owned(vp->v_interlock)); 735 736 mutex_enter(&syncer_data_lock); 737 vn_syncer_add1(vp, delayx); 738 SDT_PROBE3(vfs, syncer, worklist, vnode__add, 739 vp, delayx, vip->vi_synclist_slot); 740 mutex_exit(&syncer_data_lock); 741 } 742 743 /* 744 * Remove an item from the syncer work queue. 745 */ 746 void 747 vn_syncer_remove_from_worklist(struct vnode *vp) 748 { 749 synclist_t *slp; 750 vnode_impl_t *vip = VNODE_TO_VIMPL(vp); 751 752 KASSERT(mutex_owned(vp->v_interlock)); 753 754 if (vp->v_iflag & VI_ONWORKLST) { 755 mutex_enter(&syncer_data_lock); 756 SDT_PROBE1(vfs, syncer, worklist, vnode__remove, vp); 757 vp->v_iflag &= ~VI_ONWORKLST; 758 slp = &syncer_workitem_pending[vip->vi_synclist_slot]; 759 TAILQ_REMOVE(slp, vip, vi_synclist); 760 mutex_exit(&syncer_data_lock); 761 } 762 } 763 764 /* 765 * Add this mount point to the syncer. 766 */ 767 void 768 vfs_syncer_add_to_worklist(struct mount *mp) 769 { 770 static int start, incr, next; 771 int vdelay; 772 773 KASSERT(mutex_owned(mp->mnt_updating)); 774 KASSERT((mp->mnt_iflag & IMNT_ONWORKLIST) == 0); 775 776 /* 777 * We attempt to scatter the mount points on the list 778 * so that they will go off at evenly distributed times 779 * even if all the filesystems are mounted at once. 780 */ 781 782 next += incr; 783 if (next == 0 || next > syncer_maxdelay) { 784 start /= 2; 785 incr /= 2; 786 if (start == 0) { 787 start = syncer_maxdelay / 2; 788 incr = syncer_maxdelay; 789 } 790 next = start; 791 } 792 mp->mnt_iflag |= IMNT_ONWORKLIST; 793 vdelay = sync_delay(mp); 794 mp->mnt_synclist_slot = vdelay > 0 ? next % vdelay : 0; 795 SDT_PROBE3(vfs, syncer, worklist, mount__add, 796 mp, vdelay, mp->mnt_synclist_slot); 797 } 798 799 /* 800 * Remove the mount point from the syncer. 801 */ 802 void 803 vfs_syncer_remove_from_worklist(struct mount *mp) 804 { 805 806 KASSERT(mutex_owned(mp->mnt_updating)); 807 KASSERT((mp->mnt_iflag & IMNT_ONWORKLIST) != 0); 808 809 SDT_PROBE1(vfs, syncer, worklist, mount__remove, mp); 810 mp->mnt_iflag &= ~IMNT_ONWORKLIST; 811 } 812 813 /* 814 * Try lazy sync, return true on success. 815 */ 816 static bool 817 lazy_sync_vnode(struct vnode *vp) 818 { 819 bool synced; 820 int error; 821 822 KASSERT(mutex_owned(&syncer_data_lock)); 823 824 synced = false; 825 if ((error = vcache_tryvget(vp)) == 0) { 826 mutex_exit(&syncer_data_lock); 827 if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT)) == 0) { 828 synced = true; 829 SDT_PROBE1(vfs, syncer, sync, vnode__start, vp); 830 error = VOP_FSYNC(vp, curlwp->l_cred, 831 FSYNC_LAZY, 0, 0); 832 SDT_PROBE2(vfs, syncer, sync, vnode__done, vp, error); 833 vput(vp); 834 } else { 835 SDT_PROBE2(vfs, syncer, sync, vnode__fail__lock, 836 vp, error); 837 vrele(vp); 838 } 839 mutex_enter(&syncer_data_lock); 840 } else { 841 SDT_PROBE2(vfs, syncer, sync, vnode__fail__vget, vp, error); 842 } 843 return synced; 844 } 845 846 /* 847 * System filesystem synchronizer daemon. 848 */ 849 void 850 sched_sync(void *arg) 851 { 852 mount_iterator_t *iter; 853 synclist_t *slp; 854 struct vnode_impl *vi; 855 struct vnode *vp; 856 struct mount *mp; 857 time_t starttime, endtime; 858 int vdelay, oslot, nslot, delayx; 859 bool synced; 860 int error; 861 862 for (;;) { 863 starttime = time_second; 864 SDT_PROBE1(vfs, syncer, sync, start, starttime); 865 866 /* 867 * Sync mounts whose dirty time has expired. 868 */ 869 mountlist_iterator_init(&iter); 870 while ((mp = mountlist_iterator_trynext(iter)) != NULL) { 871 if ((mp->mnt_iflag & IMNT_ONWORKLIST) == 0 || 872 mp->mnt_synclist_slot != syncer_delayno) { 873 SDT_PROBE1(vfs, syncer, sync, mount__skip, 874 mp); 875 continue; 876 } 877 878 vdelay = sync_delay(mp); 879 oslot = mp->mnt_synclist_slot; 880 nslot = sync_delay_slot(vdelay); 881 mp->mnt_synclist_slot = nslot; 882 SDT_PROBE4(vfs, syncer, worklist, mount__update, 883 mp, vdelay, oslot, nslot); 884 885 SDT_PROBE1(vfs, syncer, sync, mount__start, mp); 886 error = VFS_SYNC(mp, MNT_LAZY, curlwp->l_cred); 887 SDT_PROBE2(vfs, syncer, sync, mount__done, 888 mp, error); 889 } 890 mountlist_iterator_destroy(iter); 891 892 mutex_enter(&syncer_data_lock); 893 894 /* 895 * Push files whose dirty time has expired. 896 */ 897 slp = &syncer_workitem_pending[syncer_delayno]; 898 syncer_delayno += 1; 899 if (syncer_delayno >= syncer_last) 900 syncer_delayno = 0; 901 902 while ((vi = TAILQ_FIRST(slp)) != NULL) { 903 vp = VIMPL_TO_VNODE(vi); 904 synced = lazy_sync_vnode(vp); 905 906 /* 907 * XXX The vnode may have been recycled, in which 908 * case it may have a new identity. 909 */ 910 vi = TAILQ_FIRST(slp); 911 if (vi != NULL && VIMPL_TO_VNODE(vi) == vp) { 912 /* 913 * Put us back on the worklist. The worklist 914 * routine will remove us from our current 915 * position and then add us back in at a later 916 * position. 917 * 918 * Try again sooner rather than later if 919 * we were unable to lock the vnode. Lock 920 * failure should not prevent us from doing 921 * the sync "soon". 922 * 923 * If we locked it yet arrive here, it's 924 * likely that lazy sync is in progress and 925 * so the vnode still has dirty metadata. 926 * syncdelay is mainly to get this vnode out 927 * of the way so we do not consider it again 928 * "soon" in this loop, so the delay time is 929 * not critical as long as it is not "soon". 930 * While write-back strategy is the file 931 * system's domain, we expect write-back to 932 * occur no later than syncdelay seconds 933 * into the future. 934 */ 935 delayx = synced ? syncdelay : lockdelay; 936 oslot = vi->vi_synclist_slot; 937 vn_syncer_add1(vp, delayx); 938 nslot = vi->vi_synclist_slot; 939 SDT_PROBE4(vfs, syncer, worklist, 940 vnode__update, 941 vp, delayx, oslot, nslot); 942 } 943 } 944 945 endtime = time_second; 946 947 SDT_PROBE2(vfs, syncer, sync, done, starttime, endtime); 948 949 /* 950 * If it has taken us less than a second to process the 951 * current work, then wait. Otherwise start right over 952 * again. We can still lose time if any single round 953 * takes more than two seconds, but it does not really 954 * matter as we are just trying to generally pace the 955 * filesystem activity. 956 */ 957 if (endtime == starttime) { 958 kpause("syncer", false, hz, &syncer_data_lock); 959 } 960 mutex_exit(&syncer_data_lock); 961 } 962 } 963 964 static void 965 sysctl_vfs_syncfs_setup(struct sysctllog **clog) 966 { 967 const struct sysctlnode *rnode, *cnode; 968 969 sysctl_createv(clog, 0, NULL, &rnode, 970 CTLFLAG_PERMANENT, 971 CTLTYPE_NODE, "sync", 972 SYSCTL_DESCR("syncer options"), 973 NULL, 0, NULL, 0, 974 CTL_VFS, CTL_CREATE, CTL_EOL); 975 976 sysctl_createv(clog, 0, &rnode, &cnode, 977 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 978 CTLTYPE_QUAD, "delay", 979 SYSCTL_DESCR("max time to delay syncing data"), 980 NULL, 0, &syncdelay, 0, 981 CTL_CREATE, CTL_EOL); 982 983 sysctl_createv(clog, 0, &rnode, &cnode, 984 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 985 CTLTYPE_QUAD, "filedelay", 986 SYSCTL_DESCR("time to delay syncing files"), 987 NULL, 0, &filedelay, 0, 988 CTL_CREATE, CTL_EOL); 989 990 sysctl_createv(clog, 0, &rnode, &cnode, 991 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 992 CTLTYPE_QUAD, "dirdelay", 993 SYSCTL_DESCR("time to delay syncing directories"), 994 NULL, 0, &dirdelay, 0, 995 CTL_CREATE, CTL_EOL); 996 997 sysctl_createv(clog, 0, &rnode, &cnode, 998 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 999 CTLTYPE_QUAD, "metadelay", 1000 SYSCTL_DESCR("time to delay syncing metadata"), 1001 NULL, 0, &metadelay, 0, 1002 CTL_CREATE, CTL_EOL); 1003 } 1004 1005 /* 1006 * sysctl helper routine to return list of supported fstypes 1007 */ 1008 int 1009 sysctl_vfs_generic_fstypes(SYSCTLFN_ARGS) 1010 { 1011 char bf[sizeof(((struct statvfs *)NULL)->f_fstypename)]; 1012 char *where = oldp; 1013 struct vfsops *v; 1014 size_t needed, left, slen; 1015 int error, first; 1016 1017 if (newp != NULL) 1018 return SET_ERROR(EPERM); 1019 if (namelen != 0) 1020 return SET_ERROR(EINVAL); 1021 1022 first = 1; 1023 error = 0; 1024 needed = 0; 1025 left = *oldlenp; 1026 1027 sysctl_unlock(); 1028 mutex_enter(&vfs_list_lock); 1029 LIST_FOREACH(v, &vfs_list, vfs_list) { 1030 if (where == NULL) 1031 needed += strlen(v->vfs_name) + 1; 1032 else { 1033 memset(bf, 0, sizeof(bf)); 1034 if (first) { 1035 strncpy(bf, v->vfs_name, sizeof(bf)); 1036 first = 0; 1037 } else { 1038 bf[0] = ' '; 1039 strncpy(bf + 1, v->vfs_name, sizeof(bf) - 1); 1040 } 1041 bf[sizeof(bf)-1] = '\0'; 1042 slen = strlen(bf); 1043 if (left < slen + 1) 1044 break; 1045 v->vfs_refcount++; 1046 mutex_exit(&vfs_list_lock); 1047 /* +1 to copy out the trailing NUL byte */ 1048 error = copyout(bf, where, slen + 1); 1049 mutex_enter(&vfs_list_lock); 1050 v->vfs_refcount--; 1051 if (error) 1052 break; 1053 where += slen; 1054 needed += slen; 1055 left -= slen; 1056 } 1057 } 1058 mutex_exit(&vfs_list_lock); 1059 sysctl_relock(); 1060 *oldlenp = needed; 1061 return error; 1062 } 1063 1064 int kinfo_vdebug = 1; 1065 int kinfo_vgetfailed; 1066 1067 #define KINFO_VNODESLOP 10 1068 1069 /* 1070 * Dump vnode list (via sysctl). 1071 * Copyout address of vnode followed by vnode. 1072 */ 1073 int 1074 sysctl_kern_vnode(SYSCTLFN_ARGS) 1075 { 1076 char *where = oldp; 1077 size_t *sizep = oldlenp; 1078 struct mount *mp; 1079 vnode_t *vp, vbuf; 1080 mount_iterator_t *iter; 1081 struct vnode_iterator *marker; 1082 char *bp = where; 1083 char *ewhere; 1084 int error; 1085 1086 if (namelen != 0) 1087 return SET_ERROR(EOPNOTSUPP); 1088 if (newp != NULL) 1089 return SET_ERROR(EPERM); 1090 1091 #define VPTRSZ sizeof(vnode_t *) 1092 #define VNODESZ sizeof(vnode_t) 1093 if (where == NULL) { 1094 *sizep = (numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ); 1095 return 0; 1096 } 1097 ewhere = where + *sizep; 1098 1099 sysctl_unlock(); 1100 mountlist_iterator_init(&iter); 1101 while ((mp = mountlist_iterator_next(iter)) != NULL) { 1102 vfs_vnode_iterator_init(mp, &marker); 1103 while ((vp = vfs_vnode_iterator_next(marker, NULL, NULL))) { 1104 if (bp + VPTRSZ + VNODESZ > ewhere) { 1105 vrele(vp); 1106 vfs_vnode_iterator_destroy(marker); 1107 mountlist_iterator_destroy(iter); 1108 sysctl_relock(); 1109 *sizep = bp - where; 1110 return SET_ERROR(ENOMEM); 1111 } 1112 memcpy(&vbuf, vp, VNODESZ); 1113 if ((error = copyout(&vp, bp, VPTRSZ)) || 1114 (error = copyout(&vbuf, bp + VPTRSZ, VNODESZ))) { 1115 vrele(vp); 1116 vfs_vnode_iterator_destroy(marker); 1117 mountlist_iterator_destroy(iter); 1118 sysctl_relock(); 1119 return error; 1120 } 1121 vrele(vp); 1122 bp += VPTRSZ + VNODESZ; 1123 } 1124 vfs_vnode_iterator_destroy(marker); 1125 } 1126 mountlist_iterator_destroy(iter); 1127 sysctl_relock(); 1128 1129 *sizep = bp - where; 1130 return 0; 1131 } 1132 1133 /* 1134 * Set vnode attributes to VNOVAL 1135 */ 1136 void 1137 vattr_null(struct vattr *vap) 1138 { 1139 1140 memset(vap, 0, sizeof(*vap)); 1141 1142 vap->va_type = VNON; 1143 1144 /* 1145 * Assign individually so that it is safe even if size and 1146 * sign of each member are varied. 1147 */ 1148 vap->va_mode = VNOVAL; 1149 vap->va_nlink = VNOVAL; 1150 vap->va_uid = VNOVAL; 1151 vap->va_gid = VNOVAL; 1152 vap->va_fsid = VNOVAL; 1153 vap->va_fileid = VNOVAL; 1154 vap->va_size = VNOVAL; 1155 vap->va_blocksize = VNOVAL; 1156 vap->va_atime.tv_sec = 1157 vap->va_mtime.tv_sec = 1158 vap->va_ctime.tv_sec = 1159 vap->va_birthtime.tv_sec = VNOVAL; 1160 vap->va_atime.tv_nsec = 1161 vap->va_mtime.tv_nsec = 1162 vap->va_ctime.tv_nsec = 1163 vap->va_birthtime.tv_nsec = VNOVAL; 1164 vap->va_gen = VNOVAL; 1165 vap->va_flags = VNOVAL; 1166 vap->va_rdev = VNOVAL; 1167 vap->va_bytes = VNOVAL; 1168 } 1169 1170 /* 1171 * Vnode state to string. 1172 */ 1173 const char * 1174 vstate_name(enum vnode_state state) 1175 { 1176 1177 switch (state) { 1178 case VS_ACTIVE: 1179 return "ACTIVE"; 1180 case VS_MARKER: 1181 return "MARKER"; 1182 case VS_LOADING: 1183 return "LOADING"; 1184 case VS_LOADED: 1185 return "LOADED"; 1186 case VS_BLOCKED: 1187 return "BLOCKED"; 1188 case VS_RECLAIMING: 1189 return "RECLAIMING"; 1190 case VS_RECLAIMED: 1191 return "RECLAIMED"; 1192 default: 1193 return "ILLEGAL"; 1194 } 1195 } 1196 1197 /* 1198 * Print a description of a vnode (common part). 1199 */ 1200 static void 1201 vprint_common(struct vnode *vp, const char *prefix, 1202 void (*pr)(const char *, ...) __printflike(1, 2)) 1203 { 1204 int n; 1205 char bf[96]; 1206 const uint8_t *cp; 1207 vnode_impl_t *vip; 1208 const char * const vnode_tags[] = { VNODE_TAGS }; 1209 const char * const vnode_types[] = { VNODE_TYPES }; 1210 const char vnode_flagbits[] = VNODE_FLAGBITS; 1211 1212 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) 1213 #define ARRAY_PRINT(idx, arr) \ 1214 ((unsigned int)(idx) < ARRAY_SIZE(arr) ? (arr)[(idx)] : "UNKNOWN") 1215 1216 vip = VNODE_TO_VIMPL(vp); 1217 1218 snprintb(bf, sizeof(bf), 1219 vnode_flagbits, vp->v_iflag | vp->v_vflag | vp->v_uflag); 1220 1221 (*pr)("vnode %p flags %s\n", vp, bf); 1222 (*pr)("%stag %s(%d) type %s(%d) mount %p typedata %p\n", prefix, 1223 ARRAY_PRINT(vp->v_tag, vnode_tags), vp->v_tag, 1224 ARRAY_PRINT(vp->v_type, vnode_types), vp->v_type, 1225 vp->v_mount, vp->v_mountedhere); 1226 (*pr)("%susecount %d writecount %d holdcount %d\n", prefix, 1227 vrefcnt(vp), vp->v_writecount, vp->v_holdcnt); 1228 (*pr)("%ssize %" PRIx64 " writesize %" PRIx64 " numoutput %d\n", 1229 prefix, vp->v_size, vp->v_writesize, vp->v_numoutput); 1230 (*pr)("%sdata %p lock %p\n", prefix, vp->v_data, &vip->vi_lock); 1231 1232 (*pr)("%sstate %s key(%p %zd)", prefix, vstate_name(vip->vi_state), 1233 vip->vi_key.vk_mount, vip->vi_key.vk_key_len); 1234 n = vip->vi_key.vk_key_len; 1235 cp = vip->vi_key.vk_key; 1236 while (n-- > 0) 1237 (*pr)(" %02x", *cp++); 1238 (*pr)("\n"); 1239 (*pr)("%slrulisthd %p\n", prefix, vip->vi_lrulisthd); 1240 1241 #undef ARRAY_PRINT 1242 #undef ARRAY_SIZE 1243 } 1244 1245 /* 1246 * Print out a description of a vnode. 1247 */ 1248 void 1249 vprint(const char *label, struct vnode *vp) 1250 { 1251 1252 if (label != NULL) 1253 printf("%s: ", label); 1254 vprint_common(vp, "\t", printf); 1255 if (vp->v_data != NULL) { 1256 printf("\t"); 1257 VOP_PRINT(vp); 1258 } 1259 } 1260 1261 /* 1262 * Given a file system name, look up the vfsops for that 1263 * file system, or return NULL if file system isn't present 1264 * in the kernel. 1265 */ 1266 struct vfsops * 1267 vfs_getopsbyname(const char *name) 1268 { 1269 struct vfsops *v; 1270 1271 mutex_enter(&vfs_list_lock); 1272 LIST_FOREACH(v, &vfs_list, vfs_list) { 1273 if (strcmp(v->vfs_name, name) == 0) 1274 break; 1275 } 1276 if (v != NULL) 1277 v->vfs_refcount++; 1278 mutex_exit(&vfs_list_lock); 1279 1280 return v; 1281 } 1282 1283 void 1284 copy_statvfs_info(struct statvfs *sbp, const struct mount *mp) 1285 { 1286 const struct statvfs *mbp; 1287 1288 if (sbp == (mbp = &mp->mnt_stat)) 1289 return; 1290 1291 (void)memcpy(&sbp->f_fsidx, &mbp->f_fsidx, sizeof(sbp->f_fsidx)); 1292 sbp->f_fsid = mbp->f_fsid; 1293 sbp->f_owner = mbp->f_owner; 1294 sbp->f_flag = mbp->f_flag; 1295 sbp->f_syncwrites = mbp->f_syncwrites; 1296 sbp->f_asyncwrites = mbp->f_asyncwrites; 1297 sbp->f_syncreads = mbp->f_syncreads; 1298 sbp->f_asyncreads = mbp->f_asyncreads; 1299 (void)memcpy(sbp->f_spare, mbp->f_spare, sizeof(mbp->f_spare)); 1300 (void)memcpy(sbp->f_fstypename, mbp->f_fstypename, 1301 sizeof(sbp->f_fstypename)); 1302 (void)memcpy(sbp->f_mntonname, mbp->f_mntonname, 1303 sizeof(sbp->f_mntonname)); 1304 (void)memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, 1305 sizeof(sbp->f_mntfromname)); 1306 (void)memcpy(sbp->f_mntfromlabel, mp->mnt_stat.f_mntfromlabel, 1307 sizeof(sbp->f_mntfromlabel)); 1308 sbp->f_namemax = mbp->f_namemax; 1309 } 1310 1311 int 1312 set_statvfs_info(const char *onp, int ukon, const char *fromp, int ukfrom, 1313 const char *vfsname, struct mount *mp, struct lwp *l) 1314 { 1315 int error; 1316 size_t size; 1317 struct statvfs *sfs = &mp->mnt_stat; 1318 int (*fun)(const void *, void *, size_t, size_t *); 1319 1320 (void)strlcpy(mp->mnt_stat.f_fstypename, vfsname, 1321 sizeof(mp->mnt_stat.f_fstypename)); 1322 1323 if (onp) { 1324 struct cwdinfo *cwdi = l->l_proc->p_cwdi; 1325 fun = (ukon == UIO_SYSSPACE) ? copystr : copyinstr; 1326 if (cwdi->cwdi_rdir != NULL) { 1327 size_t len; 1328 char *bp; 1329 char *path = PNBUF_GET(); 1330 1331 bp = path + MAXPATHLEN; 1332 *--bp = '\0'; 1333 rw_enter(&cwdi->cwdi_lock, RW_READER); 1334 error = getcwd_common(cwdi->cwdi_rdir, rootvnode, &bp, 1335 path, MAXPATHLEN / 2, 0, l); 1336 rw_exit(&cwdi->cwdi_lock); 1337 if (error) { 1338 PNBUF_PUT(path); 1339 return error; 1340 } 1341 1342 len = strlen(bp); 1343 if (len > sizeof(sfs->f_mntonname) - 1) 1344 len = sizeof(sfs->f_mntonname) - 1; 1345 (void)strncpy(sfs->f_mntonname, bp, len); 1346 PNBUF_PUT(path); 1347 1348 if (len < sizeof(sfs->f_mntonname) - 1) { 1349 error = (*fun)(onp, &sfs->f_mntonname[len], 1350 sizeof(sfs->f_mntonname) - len - 1, &size); 1351 if (error) 1352 return error; 1353 size += len; 1354 } else { 1355 size = len; 1356 } 1357 } else { 1358 error = (*fun)(onp, &sfs->f_mntonname, 1359 sizeof(sfs->f_mntonname) - 1, &size); 1360 if (error) 1361 return error; 1362 } 1363 (void)memset(sfs->f_mntonname + size, 0, 1364 sizeof(sfs->f_mntonname) - size); 1365 } 1366 1367 if (fromp) { 1368 fun = (ukfrom == UIO_SYSSPACE) ? copystr : copyinstr; 1369 error = (*fun)(fromp, sfs->f_mntfromname, 1370 sizeof(sfs->f_mntfromname) - 1, &size); 1371 if (error) 1372 return error; 1373 (void)memset(sfs->f_mntfromname + size, 0, 1374 sizeof(sfs->f_mntfromname) - size); 1375 } 1376 return 0; 1377 } 1378 1379 /* 1380 * Knob to control the precision of file timestamps: 1381 * 1382 * 0 = seconds only; nanoseconds zeroed. 1383 * 1 = seconds and nanoseconds, accurate within 1/HZ. 1384 * 2 = seconds and nanoseconds, truncated to microseconds. 1385 * >=3 = seconds and nanoseconds, maximum precision. 1386 */ 1387 enum { TSP_SEC, TSP_HZ, TSP_USEC, TSP_NSEC }; 1388 1389 int vfs_timestamp_precision __read_mostly = TSP_NSEC; 1390 1391 void 1392 vfs_timestamp(struct timespec *tsp) 1393 { 1394 struct timeval tv; 1395 1396 switch (vfs_timestamp_precision) { 1397 case TSP_SEC: 1398 tsp->tv_sec = time_second; 1399 tsp->tv_nsec = 0; 1400 break; 1401 case TSP_HZ: 1402 getnanotime(tsp); 1403 break; 1404 case TSP_USEC: 1405 microtime(&tv); 1406 TIMEVAL_TO_TIMESPEC(&tv, tsp); 1407 break; 1408 case TSP_NSEC: 1409 default: 1410 nanotime(tsp); 1411 break; 1412 } 1413 } 1414 1415 /* 1416 * The purpose of this routine is to remove granularity from accmode_t, 1417 * reducing it into standard unix access bits - VEXEC, VREAD, VWRITE, 1418 * VADMIN and VAPPEND. 1419 * 1420 * If it returns 0, the caller is supposed to continue with the usual 1421 * access checks using 'accmode' as modified by this routine. If it 1422 * returns nonzero value, the caller is supposed to return that value 1423 * as errno. 1424 * 1425 * Note that after this routine runs, accmode may be zero. 1426 */ 1427 int 1428 vfs_unixify_accmode(accmode_t *accmode) 1429 { 1430 1431 /* 1432 * There is no way to specify explicit "deny" rule using 1433 * file mode or POSIX.1e ACLs. 1434 */ 1435 if (*accmode & VEXPLICIT_DENY) { 1436 *accmode = 0; 1437 return 0; 1438 } 1439 1440 /* 1441 * None of these can be translated into usual access bits. 1442 * Also, the common case for NFSv4 ACLs is to not contain 1443 * either of these bits. Caller should check for VWRITE 1444 * on the containing directory instead. 1445 */ 1446 if (*accmode & (VDELETE_CHILD | VDELETE)) 1447 return SET_ERROR(EPERM); 1448 1449 if (*accmode & VADMIN_PERMS) { 1450 *accmode &= ~VADMIN_PERMS; 1451 *accmode |= VADMIN; 1452 } 1453 1454 /* 1455 * There is no way to deny VREAD_ATTRIBUTES, VREAD_ACL 1456 * or VSYNCHRONIZE using file mode or POSIX.1e ACL. 1457 */ 1458 *accmode &= ~(VSTAT_PERMS | VSYNCHRONIZE); 1459 1460 return 0; 1461 } 1462 1463 time_t rootfstime; /* recorded root fs time, if known */ 1464 void 1465 setrootfstime(time_t t) 1466 { 1467 1468 rootfstime = t; 1469 } 1470 1471 static const uint8_t vttodt_tab[] = { 1472 [VNON] = DT_UNKNOWN, 1473 [VREG] = DT_REG, 1474 [VDIR] = DT_DIR, 1475 [VBLK] = DT_BLK, 1476 [VCHR] = DT_CHR, 1477 [VLNK] = DT_LNK, 1478 [VSOCK] = DT_SOCK, 1479 [VFIFO] = DT_FIFO, 1480 [VBAD] = DT_UNKNOWN 1481 }; 1482 1483 uint8_t 1484 vtype2dt(enum vtype vt) 1485 { 1486 1487 CTASSERT(VBAD == __arraycount(vttodt_tab) - 1); 1488 return vttodt_tab[vt]; 1489 } 1490 1491 int 1492 VFS_MOUNT(struct mount *mp, const char *a, void *b, size_t *c) 1493 { 1494 int mpsafe = mp->mnt_iflag & IMNT_MPSAFE; 1495 int error; 1496 1497 /* 1498 * Note: The first time through, the vfs_mount function may set 1499 * IMNT_MPSAFE, so we have to cache it on entry in order to 1500 * avoid leaking a kernel lock. 1501 * 1502 * XXX Maybe the MPSAFE bit should be set in struct vfsops and 1503 * not in struct mount. 1504 */ 1505 if (!mpsafe) { 1506 KERNEL_LOCK(1, NULL); 1507 } 1508 error = (*(mp->mnt_op->vfs_mount))(mp, a, b, c); 1509 if (!mpsafe) { 1510 KERNEL_UNLOCK_ONE(NULL); 1511 } 1512 1513 return error; 1514 } 1515 1516 int 1517 VFS_START(struct mount *mp, int a) 1518 { 1519 int error; 1520 1521 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1522 KERNEL_LOCK(1, NULL); 1523 } 1524 error = (*(mp->mnt_op->vfs_start))(mp, a); 1525 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1526 KERNEL_UNLOCK_ONE(NULL); 1527 } 1528 1529 return error; 1530 } 1531 1532 int 1533 VFS_UNMOUNT(struct mount *mp, int a) 1534 { 1535 int error; 1536 1537 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1538 KERNEL_LOCK(1, NULL); 1539 } 1540 error = (*(mp->mnt_op->vfs_unmount))(mp, a); 1541 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1542 KERNEL_UNLOCK_ONE(NULL); 1543 } 1544 1545 return error; 1546 } 1547 1548 int 1549 VFS_ROOT(struct mount *mp, int lktype, struct vnode **a) 1550 { 1551 int error; 1552 1553 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1554 KERNEL_LOCK(1, NULL); 1555 } 1556 error = (*(mp->mnt_op->vfs_root))(mp, lktype, a); 1557 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1558 KERNEL_UNLOCK_ONE(NULL); 1559 } 1560 1561 return error; 1562 } 1563 1564 int 1565 VFS_QUOTACTL(struct mount *mp, struct quotactl_args *args) 1566 { 1567 int error; 1568 1569 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1570 KERNEL_LOCK(1, NULL); 1571 } 1572 error = (*(mp->mnt_op->vfs_quotactl))(mp, args); 1573 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1574 KERNEL_UNLOCK_ONE(NULL); 1575 } 1576 1577 return error; 1578 } 1579 1580 int 1581 VFS_STATVFS(struct mount *mp, struct statvfs *a) 1582 { 1583 int error; 1584 1585 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1586 KERNEL_LOCK(1, NULL); 1587 } 1588 error = (*(mp->mnt_op->vfs_statvfs))(mp, a); 1589 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1590 KERNEL_UNLOCK_ONE(NULL); 1591 } 1592 1593 return error; 1594 } 1595 1596 int 1597 VFS_SYNC(struct mount *mp, int a, struct kauth_cred *b) 1598 { 1599 int error; 1600 1601 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1602 KERNEL_LOCK(1, NULL); 1603 } 1604 error = (*(mp->mnt_op->vfs_sync))(mp, a, b); 1605 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1606 KERNEL_UNLOCK_ONE(NULL); 1607 } 1608 1609 return error; 1610 } 1611 1612 int 1613 VFS_FHTOVP(struct mount *mp, struct fid *a, int b, struct vnode **c) 1614 { 1615 int error; 1616 1617 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1618 KERNEL_LOCK(1, NULL); 1619 } 1620 error = (*(mp->mnt_op->vfs_fhtovp))(mp, a, b, c); 1621 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1622 KERNEL_UNLOCK_ONE(NULL); 1623 } 1624 1625 return error; 1626 } 1627 1628 int 1629 VFS_VPTOFH(struct vnode *vp, struct fid *a, size_t *b) 1630 { 1631 int error; 1632 1633 if ((vp->v_vflag & VV_MPSAFE) == 0) { 1634 KERNEL_LOCK(1, NULL); 1635 } 1636 error = (*(vp->v_mount->mnt_op->vfs_vptofh))(vp, a, b); 1637 if ((vp->v_vflag & VV_MPSAFE) == 0) { 1638 KERNEL_UNLOCK_ONE(NULL); 1639 } 1640 1641 return error; 1642 } 1643 1644 int 1645 VFS_SNAPSHOT(struct mount *mp, struct vnode *a, struct timespec *b) 1646 { 1647 int error; 1648 1649 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1650 KERNEL_LOCK(1, NULL); 1651 } 1652 error = (*(mp->mnt_op->vfs_snapshot))(mp, a, b); 1653 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1654 KERNEL_UNLOCK_ONE(NULL); 1655 } 1656 1657 return error; 1658 } 1659 1660 int 1661 VFS_EXTATTRCTL(struct mount *mp, int a, struct vnode *b, int c, const char *d) 1662 { 1663 int error; 1664 1665 KERNEL_LOCK(1, NULL); /* XXXSMP check ffs */ 1666 error = (*(mp->mnt_op->vfs_extattrctl))(mp, a, b, c, d); 1667 KERNEL_UNLOCK_ONE(NULL); /* XXX */ 1668 1669 return error; 1670 } 1671 1672 int 1673 VFS_SUSPENDCTL(struct mount *mp, int a) 1674 { 1675 int error; 1676 1677 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1678 KERNEL_LOCK(1, NULL); 1679 } 1680 error = (*(mp->mnt_op->vfs_suspendctl))(mp, a); 1681 if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { 1682 KERNEL_UNLOCK_ONE(NULL); 1683 } 1684 1685 return error; 1686 } 1687 1688 #if defined(DDB) || defined(DEBUGPRINT) 1689 static const char buf_flagbits[] = BUF_FLAGBITS; 1690 1691 void 1692 vfs_buf_print(struct buf *bp, int full, void (*pr)(const char *, ...)) 1693 { 1694 char bf[1024]; 1695 1696 (*pr)(" vp %p lblkno 0x%"PRIx64" blkno 0x%"PRIx64" rawblkno 0x%" 1697 PRIx64 " dev 0x%x\n", 1698 bp->b_vp, bp->b_lblkno, bp->b_blkno, bp->b_rawblkno, bp->b_dev); 1699 1700 snprintb(bf, sizeof(bf), 1701 buf_flagbits, bp->b_flags | bp->b_oflags | bp->b_cflags); 1702 (*pr)(" error %d flags %s\n", bp->b_error, bf); 1703 1704 (*pr)(" bufsize 0x%lx bcount 0x%lx resid 0x%lx\n", 1705 bp->b_bufsize, bp->b_bcount, bp->b_resid); 1706 (*pr)(" data %p saveaddr %p\n", 1707 bp->b_data, bp->b_saveaddr); 1708 (*pr)(" iodone %p objlock %p\n", bp->b_iodone, bp->b_objlock); 1709 } 1710 1711 void 1712 vfs_vnode_print(struct vnode *vp, int full, void (*pr)(const char *, ...)) 1713 { 1714 1715 uvm_object_printit(&vp->v_uobj, full, pr); 1716 (*pr)("\n"); 1717 vprint_common(vp, "", pr); 1718 if (full) { 1719 struct buf *bp; 1720 1721 (*pr)("clean bufs:\n"); 1722 LIST_FOREACH(bp, &vp->v_cleanblkhd, b_vnbufs) { 1723 (*pr)(" bp %p\n", bp); 1724 vfs_buf_print(bp, full, pr); 1725 } 1726 1727 (*pr)("dirty bufs:\n"); 1728 LIST_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) { 1729 (*pr)(" bp %p\n", bp); 1730 vfs_buf_print(bp, full, pr); 1731 } 1732 } 1733 } 1734 1735 void 1736 vfs_vnode_lock_print(void *vlock, int full, void (*pr)(const char *, ...)) 1737 { 1738 struct mount *mp; 1739 vnode_impl_t *vip; 1740 1741 for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) { 1742 TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { 1743 if (&vip->vi_lock == vlock || 1744 VIMPL_TO_VNODE(vip)->v_interlock == vlock) 1745 vfs_vnode_print(VIMPL_TO_VNODE(vip), full, pr); 1746 } 1747 } 1748 } 1749 1750 void 1751 vfs_mount_print_all(int full, void (*pr)(const char *, ...)) 1752 { 1753 struct mount *mp; 1754 for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) 1755 vfs_mount_print(mp, full, pr); 1756 } 1757 1758 void 1759 vfs_mount_print(struct mount *mp, int full, void (*pr)(const char *, ...)) 1760 { 1761 char sbuf[256]; 1762 1763 (*pr)("vnodecovered = %p data = %p\n", 1764 mp->mnt_vnodecovered, mp->mnt_data); 1765 1766 (*pr)("fs_bshift %d dev_bshift = %d\n", 1767 mp->mnt_fs_bshift, mp->mnt_dev_bshift); 1768 1769 snprintb(sbuf, sizeof(sbuf), __MNT_FLAG_BITS, mp->mnt_flag); 1770 (*pr)("flag = %s\n", sbuf); 1771 1772 snprintb(sbuf, sizeof(sbuf), __IMNT_FLAG_BITS, mp->mnt_iflag); 1773 (*pr)("iflag = %s\n", sbuf); 1774 1775 (*pr)("refcnt = %d updating @ %p\n", mp->mnt_refcnt, mp->mnt_updating); 1776 1777 (*pr)("statvfs cache:\n"); 1778 (*pr)("\tbsize = %lu\n", mp->mnt_stat.f_bsize); 1779 (*pr)("\tfrsize = %lu\n", mp->mnt_stat.f_frsize); 1780 (*pr)("\tiosize = %lu\n", mp->mnt_stat.f_iosize); 1781 1782 (*pr)("\tblocks = %"PRIu64"\n", mp->mnt_stat.f_blocks); 1783 (*pr)("\tbfree = %"PRIu64"\n", mp->mnt_stat.f_bfree); 1784 (*pr)("\tbavail = %"PRIu64"\n", mp->mnt_stat.f_bavail); 1785 (*pr)("\tbresvd = %"PRIu64"\n", mp->mnt_stat.f_bresvd); 1786 1787 (*pr)("\tfiles = %"PRIu64"\n", mp->mnt_stat.f_files); 1788 (*pr)("\tffree = %"PRIu64"\n", mp->mnt_stat.f_ffree); 1789 (*pr)("\tfavail = %"PRIu64"\n", mp->mnt_stat.f_favail); 1790 (*pr)("\tfresvd = %"PRIu64"\n", mp->mnt_stat.f_fresvd); 1791 1792 (*pr)("\tf_fsidx = { 0x%"PRIx32", 0x%"PRIx32" }\n", 1793 mp->mnt_stat.f_fsidx.__fsid_val[0], 1794 mp->mnt_stat.f_fsidx.__fsid_val[1]); 1795 1796 (*pr)("\towner = %"PRIu32"\n", mp->mnt_stat.f_owner); 1797 (*pr)("\tnamemax = %lu\n", mp->mnt_stat.f_namemax); 1798 1799 snprintb(sbuf, sizeof(sbuf), __MNT_FLAG_BITS, mp->mnt_stat.f_flag); 1800 1801 (*pr)("\tflag = %s\n", sbuf); 1802 (*pr)("\tsyncwrites = %" PRIu64 "\n", mp->mnt_stat.f_syncwrites); 1803 (*pr)("\tasyncwrites = %" PRIu64 "\n", mp->mnt_stat.f_asyncwrites); 1804 (*pr)("\tsyncreads = %" PRIu64 "\n", mp->mnt_stat.f_syncreads); 1805 (*pr)("\tasyncreads = %" PRIu64 "\n", mp->mnt_stat.f_asyncreads); 1806 (*pr)("\tfstypename = %s\n", mp->mnt_stat.f_fstypename); 1807 (*pr)("\tmntonname = %s\n", mp->mnt_stat.f_mntonname); 1808 (*pr)("\tmntfromname = %s\n", mp->mnt_stat.f_mntfromname); 1809 1810 { 1811 int cnt = 0; 1812 vnode_t *vp; 1813 vnode_impl_t *vip; 1814 (*pr)("locked vnodes ="); 1815 TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { 1816 vp = VIMPL_TO_VNODE(vip); 1817 if (VOP_ISLOCKED(vp)) { 1818 if ((++cnt % 6) == 0) { 1819 (*pr)(" %p,\n\t", vp); 1820 } else { 1821 (*pr)(" %p,", vp); 1822 } 1823 } 1824 } 1825 (*pr)("\n"); 1826 } 1827 1828 if (full) { 1829 int cnt = 0; 1830 vnode_t *vp; 1831 vnode_impl_t *vip; 1832 1833 (*pr)("all vnodes ="); 1834 TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { 1835 vp = VIMPL_TO_VNODE(vip); 1836 if (!TAILQ_NEXT(vip, vi_mntvnodes)) { 1837 (*pr)(" %p", vp); 1838 } else if ((++cnt % 6) == 0) { 1839 (*pr)(" %p,\n\t", vp); 1840 } else { 1841 (*pr)(" %p,", vp); 1842 } 1843 } 1844 (*pr)("\n"); 1845 } 1846 } 1847 1848 /* 1849 * List all of the locked vnodes in the system. 1850 */ 1851 void printlockedvnodes(void); 1852 1853 void 1854 printlockedvnodes(void) 1855 { 1856 struct mount *mp; 1857 vnode_t *vp; 1858 vnode_impl_t *vip; 1859 1860 printf("Locked vnodes\n"); 1861 for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) { 1862 TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { 1863 vp = VIMPL_TO_VNODE(vip); 1864 if (VOP_ISLOCKED(vp)) 1865 vprint(NULL, vp); 1866 } 1867 } 1868 } 1869 1870 #endif /* DDB || DEBUGPRINT */ 1871