1 /*- 2 * Copyright (c) 1999-2004 Poul-Henning Kamp 3 * Copyright (c) 1999 Michael Smith 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 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #include <sys/cdefs.h> 38 __FBSDID("$FreeBSD$"); 39 40 #include <sys/param.h> 41 #include <sys/conf.h> 42 #include <sys/clock.h> 43 #include <sys/jail.h> 44 #include <sys/kernel.h> 45 #include <sys/libkern.h> 46 #include <sys/malloc.h> 47 #include <sys/mount.h> 48 #include <sys/mutex.h> 49 #include <sys/namei.h> 50 #include <sys/priv.h> 51 #include <sys/proc.h> 52 #include <sys/filedesc.h> 53 #include <sys/reboot.h> 54 #include <sys/syscallsubr.h> 55 #include <sys/sysproto.h> 56 #include <sys/sx.h> 57 #include <sys/sysctl.h> 58 #include <sys/sysent.h> 59 #include <sys/systm.h> 60 #include <sys/vnode.h> 61 #include <vm/uma.h> 62 63 #include <geom/geom.h> 64 65 #include <machine/stdarg.h> 66 67 #include <security/audit/audit.h> 68 #include <security/mac/mac_framework.h> 69 70 #include "opt_rootdevname.h" 71 #include "opt_ddb.h" 72 #include "opt_mac.h" 73 74 #ifdef DDB 75 #include <ddb/ddb.h> 76 #endif 77 78 #define ROOTNAME "root_device" 79 #define VFS_MOUNTARG_SIZE_MAX (1024 * 64) 80 81 static int vfs_domount(struct thread *td, const char *fstype, 82 char *fspath, int fsflags, void *fsdata); 83 static struct mount *vfs_mount_alloc(struct vnode *dvp, struct vfsconf *vfsp, 84 const char *fspath, struct thread *td); 85 static int vfs_mountroot_ask(void); 86 static int vfs_mountroot_try(const char *mountfrom); 87 static int vfs_donmount(struct thread *td, int fsflags, 88 struct uio *fsoptions); 89 static void free_mntarg(struct mntarg *ma); 90 static void vfs_mount_destroy(struct mount *); 91 static int vfs_getopt_pos(struct vfsoptlist *opts, const char *name); 92 93 static int usermount = 0; 94 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, 95 "Unprivileged users may mount and unmount file systems"); 96 97 MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure"); 98 MALLOC_DEFINE(M_VNODE_MARKER, "vnodemarker", "vnode marker"); 99 static uma_zone_t mount_zone; 100 101 /* List of mounted filesystems. */ 102 struct mntlist mountlist = TAILQ_HEAD_INITIALIZER(mountlist); 103 104 /* For any iteration/modification of mountlist */ 105 struct mtx mountlist_mtx; 106 MTX_SYSINIT(mountlist, &mountlist_mtx, "mountlist", MTX_DEF); 107 108 TAILQ_HEAD(vfsoptlist, vfsopt); 109 struct vfsopt { 110 TAILQ_ENTRY(vfsopt) link; 111 char *name; 112 void *value; 113 int len; 114 }; 115 116 /* 117 * The vnode of the system's root (/ in the filesystem, without chroot 118 * active.) 119 */ 120 struct vnode *rootvnode; 121 122 /* 123 * The root filesystem is detailed in the kernel environment variable 124 * vfs.root.mountfrom, which is expected to be in the general format 125 * 126 * <vfsname>:[<path>] 127 * vfsname := the name of a VFS known to the kernel and capable 128 * of being mounted as root 129 * path := disk device name or other data used by the filesystem 130 * to locate its physical store 131 */ 132 133 /* 134 * Global opts, taken by all filesystems 135 */ 136 static const char *global_opts[] = { 137 "errmsg", 138 "fstype", 139 "fspath", 140 "rdonly", 141 "ro", 142 "rw", 143 "suid", 144 "exec", 145 "update", 146 NULL 147 }; 148 149 /* 150 * The root specifiers we will try if RB_CDROM is specified. 151 */ 152 static char *cdrom_rootdevnames[] = { 153 "cd9660:cd0", 154 "cd9660:acd0", 155 NULL 156 }; 157 158 /* legacy find-root code */ 159 char *rootdevnames[2] = {NULL, NULL}; 160 #ifndef ROOTDEVNAME 161 # define ROOTDEVNAME NULL 162 #endif 163 static const char *ctrootdevname = ROOTDEVNAME; 164 165 /* 166 * --------------------------------------------------------------------- 167 * Functions for building and sanitizing the mount options 168 */ 169 170 /* Remove one mount option. */ 171 static void 172 vfs_freeopt(struct vfsoptlist *opts, struct vfsopt *opt) 173 { 174 175 TAILQ_REMOVE(opts, opt, link); 176 free(opt->name, M_MOUNT); 177 if (opt->value != NULL) 178 free(opt->value, M_MOUNT); 179 #ifdef INVARIANTS 180 else if (opt->len != 0) 181 panic("%s: mount option with NULL value but length != 0", 182 __func__); 183 #endif 184 free(opt, M_MOUNT); 185 } 186 187 /* Release all resources related to the mount options. */ 188 static void 189 vfs_freeopts(struct vfsoptlist *opts) 190 { 191 struct vfsopt *opt; 192 193 while (!TAILQ_EMPTY(opts)) { 194 opt = TAILQ_FIRST(opts); 195 vfs_freeopt(opts, opt); 196 } 197 free(opts, M_MOUNT); 198 } 199 200 void 201 vfs_deleteopt(struct vfsoptlist *opts, const char *name) 202 { 203 struct vfsopt *opt, *temp; 204 205 TAILQ_FOREACH_SAFE(opt, opts, link, temp) { 206 if (strcmp(opt->name, name) == 0) 207 vfs_freeopt(opts, opt); 208 } 209 } 210 211 /* 212 * Check if options are equal (with or without the "no" prefix). 213 */ 214 static int 215 vfs_equalopts(const char *opt1, const char *opt2) 216 { 217 218 /* "opt" vs. "opt" or "noopt" vs. "noopt" */ 219 if (strcmp(opt1, opt2) == 0) 220 return (1); 221 /* "noopt" vs. "opt" */ 222 if (strncmp(opt1, "no", 2) == 0 && strcmp(opt1 + 2, opt2) == 0) 223 return (1); 224 /* "opt" vs. "noopt" */ 225 if (strncmp(opt2, "no", 2) == 0 && strcmp(opt1, opt2 + 2) == 0) 226 return (1); 227 return (0); 228 } 229 230 /* 231 * If a mount option is specified several times, 232 * (with or without the "no" prefix) only keep 233 * the last occurence of it. 234 */ 235 static void 236 vfs_sanitizeopts(struct vfsoptlist *opts) 237 { 238 struct vfsopt *opt, *opt2, *tmp; 239 240 TAILQ_FOREACH_REVERSE(opt, opts, vfsoptlist, link) { 241 opt2 = TAILQ_PREV(opt, vfsoptlist, link); 242 while (opt2 != NULL) { 243 if (vfs_equalopts(opt->name, opt2->name)) { 244 tmp = TAILQ_PREV(opt2, vfsoptlist, link); 245 vfs_freeopt(opts, opt2); 246 opt2 = tmp; 247 } else { 248 opt2 = TAILQ_PREV(opt2, vfsoptlist, link); 249 } 250 } 251 } 252 } 253 254 /* 255 * Build a linked list of mount options from a struct uio. 256 */ 257 static int 258 vfs_buildopts(struct uio *auio, struct vfsoptlist **options) 259 { 260 struct vfsoptlist *opts; 261 struct vfsopt *opt; 262 size_t memused; 263 unsigned int i, iovcnt; 264 int error, namelen, optlen; 265 266 opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); 267 TAILQ_INIT(opts); 268 memused = 0; 269 iovcnt = auio->uio_iovcnt; 270 for (i = 0; i < iovcnt; i += 2) { 271 opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK); 272 namelen = auio->uio_iov[i].iov_len; 273 optlen = auio->uio_iov[i + 1].iov_len; 274 opt->name = malloc(namelen, M_MOUNT, M_WAITOK); 275 opt->value = NULL; 276 opt->len = 0; 277 278 /* 279 * Do this early, so jumps to "bad" will free the current 280 * option. 281 */ 282 TAILQ_INSERT_TAIL(opts, opt, link); 283 memused += sizeof(struct vfsopt) + optlen + namelen; 284 285 /* 286 * Avoid consuming too much memory, and attempts to overflow 287 * memused. 288 */ 289 if (memused > VFS_MOUNTARG_SIZE_MAX || 290 optlen > VFS_MOUNTARG_SIZE_MAX || 291 namelen > VFS_MOUNTARG_SIZE_MAX) { 292 error = EINVAL; 293 goto bad; 294 } 295 296 if (auio->uio_segflg == UIO_SYSSPACE) { 297 bcopy(auio->uio_iov[i].iov_base, opt->name, namelen); 298 } else { 299 error = copyin(auio->uio_iov[i].iov_base, opt->name, 300 namelen); 301 if (error) 302 goto bad; 303 } 304 /* Ensure names are null-terminated strings. */ 305 if (opt->name[namelen - 1] != '\0') { 306 error = EINVAL; 307 goto bad; 308 } 309 if (optlen != 0) { 310 opt->len = optlen; 311 opt->value = malloc(optlen, M_MOUNT, M_WAITOK); 312 if (auio->uio_segflg == UIO_SYSSPACE) { 313 bcopy(auio->uio_iov[i + 1].iov_base, opt->value, 314 optlen); 315 } else { 316 error = copyin(auio->uio_iov[i + 1].iov_base, 317 opt->value, optlen); 318 if (error) 319 goto bad; 320 } 321 } 322 } 323 vfs_sanitizeopts(opts); 324 *options = opts; 325 return (0); 326 bad: 327 vfs_freeopts(opts); 328 return (error); 329 } 330 331 /* 332 * Merge the old mount options with the new ones passed 333 * in the MNT_UPDATE case. 334 */ 335 static void 336 vfs_mergeopts(struct vfsoptlist *toopts, struct vfsoptlist *opts) 337 { 338 struct vfsopt *opt, *opt2, *new; 339 340 TAILQ_FOREACH(opt, opts, link) { 341 /* 342 * Check that this option hasn't been redefined 343 * nor cancelled with a "no" mount option. 344 */ 345 opt2 = TAILQ_FIRST(toopts); 346 while (opt2 != NULL) { 347 if (strcmp(opt2->name, opt->name) == 0) 348 goto next; 349 if (strncmp(opt2->name, "no", 2) == 0 && 350 strcmp(opt2->name + 2, opt->name) == 0) { 351 vfs_freeopt(toopts, opt2); 352 goto next; 353 } 354 opt2 = TAILQ_NEXT(opt2, link); 355 } 356 /* We want this option, duplicate it. */ 357 new = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK); 358 new->name = malloc(strlen(opt->name) + 1, M_MOUNT, M_WAITOK); 359 strcpy(new->name, opt->name); 360 if (opt->len != 0) { 361 new->value = malloc(opt->len, M_MOUNT, M_WAITOK); 362 bcopy(opt->value, new->value, opt->len); 363 } else { 364 new->value = NULL; 365 } 366 new->len = opt->len; 367 TAILQ_INSERT_TAIL(toopts, new, link); 368 next: 369 continue; 370 } 371 } 372 373 /* 374 * --------------------------------------------------------------------- 375 * Mount a filesystem 376 */ 377 int 378 nmount(td, uap) 379 struct thread *td; 380 struct nmount_args /* { 381 struct iovec *iovp; 382 unsigned int iovcnt; 383 int flags; 384 } */ *uap; 385 { 386 struct uio *auio; 387 struct iovec *iov; 388 unsigned int i; 389 int error; 390 u_int iovcnt; 391 392 AUDIT_ARG(fflags, uap->flags); 393 394 /* Kick out MNT_ROOTFS early as it is legal internally */ 395 if (uap->flags & MNT_ROOTFS) 396 return (EINVAL); 397 398 iovcnt = uap->iovcnt; 399 /* 400 * Check that we have an even number of iovec's 401 * and that we have at least two options. 402 */ 403 if ((iovcnt & 1) || (iovcnt < 4)) 404 return (EINVAL); 405 406 error = copyinuio(uap->iovp, iovcnt, &auio); 407 if (error) 408 return (error); 409 iov = auio->uio_iov; 410 for (i = 0; i < iovcnt; i++) { 411 if (iov->iov_len > MMAXOPTIONLEN) { 412 free(auio, M_IOV); 413 return (EINVAL); 414 } 415 iov++; 416 } 417 error = vfs_donmount(td, uap->flags, auio); 418 419 free(auio, M_IOV); 420 return (error); 421 } 422 423 /* 424 * --------------------------------------------------------------------- 425 * Various utility functions 426 */ 427 428 void 429 vfs_ref(struct mount *mp) 430 { 431 432 MNT_ILOCK(mp); 433 MNT_REF(mp); 434 MNT_IUNLOCK(mp); 435 } 436 437 void 438 vfs_rel(struct mount *mp) 439 { 440 441 MNT_ILOCK(mp); 442 MNT_REL(mp); 443 MNT_IUNLOCK(mp); 444 } 445 446 static int 447 mount_init(void *mem, int size, int flags) 448 { 449 struct mount *mp; 450 451 mp = (struct mount *)mem; 452 mtx_init(&mp->mnt_mtx, "struct mount mtx", NULL, MTX_DEF); 453 lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0); 454 return (0); 455 } 456 457 static void 458 mount_fini(void *mem, int size) 459 { 460 struct mount *mp; 461 462 mp = (struct mount *)mem; 463 lockdestroy(&mp->mnt_lock); 464 mtx_destroy(&mp->mnt_mtx); 465 } 466 467 /* 468 * Allocate and initialize the mount point struct. 469 */ 470 static struct mount * 471 vfs_mount_alloc(struct vnode *vp, struct vfsconf *vfsp, 472 const char *fspath, struct thread *td) 473 { 474 struct mount *mp; 475 476 mp = uma_zalloc(mount_zone, M_WAITOK); 477 bzero(&mp->mnt_startzero, 478 __rangeof(struct mount, mnt_startzero, mnt_endzero)); 479 TAILQ_INIT(&mp->mnt_nvnodelist); 480 mp->mnt_nvnodelistsize = 0; 481 mp->mnt_ref = 0; 482 (void) vfs_busy(mp, LK_NOWAIT, 0, td); 483 mp->mnt_op = vfsp->vfc_vfsops; 484 mp->mnt_vfc = vfsp; 485 vfsp->vfc_refcount++; /* XXX Unlocked */ 486 mp->mnt_stat.f_type = vfsp->vfc_typenum; 487 MNT_ILOCK(mp); 488 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK; 489 MNT_IUNLOCK(mp); 490 mp->mnt_gen++; 491 strlcpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN); 492 mp->mnt_vnodecovered = vp; 493 mp->mnt_cred = crdup(td->td_ucred); 494 mp->mnt_stat.f_owner = td->td_ucred->cr_uid; 495 strlcpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN); 496 mp->mnt_iosize_max = DFLTPHYS; 497 #ifdef MAC 498 mac_init_mount(mp); 499 mac_create_mount(td->td_ucred, mp); 500 #endif 501 arc4rand(&mp->mnt_hashseed, sizeof mp->mnt_hashseed, 0); 502 return (mp); 503 } 504 505 /* 506 * Destroy the mount struct previously allocated by vfs_mount_alloc(). 507 */ 508 static void 509 vfs_mount_destroy(struct mount *mp) 510 { 511 int i; 512 513 MNT_ILOCK(mp); 514 for (i = 0; mp->mnt_ref && i < 3; i++) 515 msleep(mp, MNT_MTX(mp), PVFS, "mntref", hz); 516 /* 517 * This will always cause a 3 second delay in rebooting due to 518 * refs on the root mountpoint that never go away. Most of these 519 * are held by init which never exits. 520 */ 521 if (i == 3 && (!rebooting || bootverbose)) 522 printf("Mount point %s had %d dangling refs\n", 523 mp->mnt_stat.f_mntonname, mp->mnt_ref); 524 if (mp->mnt_holdcnt != 0) { 525 printf("Waiting for mount point to be unheld\n"); 526 while (mp->mnt_holdcnt != 0) { 527 mp->mnt_holdcntwaiters++; 528 msleep(&mp->mnt_holdcnt, MNT_MTX(mp), 529 PZERO, "mntdestroy", 0); 530 mp->mnt_holdcntwaiters--; 531 } 532 printf("mount point unheld\n"); 533 } 534 if (mp->mnt_writeopcount > 0) { 535 printf("Waiting for mount point write ops\n"); 536 while (mp->mnt_writeopcount > 0) { 537 mp->mnt_kern_flag |= MNTK_SUSPEND; 538 msleep(&mp->mnt_writeopcount, 539 MNT_MTX(mp), 540 PZERO, "mntdestroy2", 0); 541 } 542 printf("mount point write ops completed\n"); 543 } 544 if (mp->mnt_secondary_writes > 0) { 545 printf("Waiting for mount point secondary write ops\n"); 546 while (mp->mnt_secondary_writes > 0) { 547 mp->mnt_kern_flag |= MNTK_SUSPEND; 548 msleep(&mp->mnt_secondary_writes, 549 MNT_MTX(mp), 550 PZERO, "mntdestroy3", 0); 551 } 552 printf("mount point secondary write ops completed\n"); 553 } 554 MNT_IUNLOCK(mp); 555 mp->mnt_vfc->vfc_refcount--; 556 if (!TAILQ_EMPTY(&mp->mnt_nvnodelist)) { 557 struct vnode *vp; 558 559 TAILQ_FOREACH(vp, &mp->mnt_nvnodelist, v_nmntvnodes) 560 vprint("", vp); 561 panic("unmount: dangling vnode"); 562 } 563 MNT_ILOCK(mp); 564 if (mp->mnt_kern_flag & MNTK_MWAIT) 565 wakeup(mp); 566 if (mp->mnt_writeopcount != 0) 567 panic("vfs_mount_destroy: nonzero writeopcount"); 568 if (mp->mnt_secondary_writes != 0) 569 panic("vfs_mount_destroy: nonzero secondary_writes"); 570 if (mp->mnt_nvnodelistsize != 0) 571 panic("vfs_mount_destroy: nonzero nvnodelistsize"); 572 mp->mnt_writeopcount = -1000; 573 mp->mnt_nvnodelistsize = -1000; 574 mp->mnt_secondary_writes = -1000; 575 MNT_IUNLOCK(mp); 576 #ifdef MAC 577 mac_destroy_mount(mp); 578 #endif 579 if (mp->mnt_opt != NULL) 580 vfs_freeopts(mp->mnt_opt); 581 crfree(mp->mnt_cred); 582 uma_zfree(mount_zone, mp); 583 } 584 585 static int 586 vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions) 587 { 588 struct vfsoptlist *optlist; 589 struct vfsopt *opt, *noro_opt; 590 char *fstype, *fspath, *errmsg; 591 int error, fstypelen, fspathlen, errmsg_len, errmsg_pos; 592 int has_rw, has_noro; 593 594 errmsg = NULL; 595 errmsg_len = 0; 596 errmsg_pos = -1; 597 has_rw = 0; 598 has_noro = 0; 599 600 error = vfs_buildopts(fsoptions, &optlist); 601 if (error) 602 return (error); 603 604 if (vfs_getopt(optlist, "errmsg", (void **)&errmsg, &errmsg_len) == 0) 605 errmsg_pos = vfs_getopt_pos(optlist, "errmsg"); 606 607 /* 608 * We need these two options before the others, 609 * and they are mandatory for any filesystem. 610 * Ensure they are NUL terminated as well. 611 */ 612 fstypelen = 0; 613 error = vfs_getopt(optlist, "fstype", (void **)&fstype, &fstypelen); 614 if (error || fstype[fstypelen - 1] != '\0') { 615 error = EINVAL; 616 if (errmsg != NULL) 617 strncpy(errmsg, "Invalid fstype", errmsg_len); 618 goto bail; 619 } 620 fspathlen = 0; 621 error = vfs_getopt(optlist, "fspath", (void **)&fspath, &fspathlen); 622 if (error || fspath[fspathlen - 1] != '\0') { 623 error = EINVAL; 624 if (errmsg != NULL) 625 strncpy(errmsg, "Invalid fspath", errmsg_len); 626 goto bail; 627 } 628 629 /* 630 * We need to see if we have the "update" option 631 * before we call vfs_domount(), since vfs_domount() has special 632 * logic based on MNT_UPDATE. This is very important 633 * when we want to update the root filesystem. 634 */ 635 TAILQ_FOREACH(opt, optlist, link) { 636 if (strcmp(opt->name, "update") == 0) 637 fsflags |= MNT_UPDATE; 638 else if (strcmp(opt->name, "async") == 0) 639 fsflags |= MNT_ASYNC; 640 else if (strcmp(opt->name, "force") == 0) 641 fsflags |= MNT_FORCE; 642 else if (strcmp(opt->name, "multilabel") == 0) 643 fsflags |= MNT_MULTILABEL; 644 else if (strcmp(opt->name, "noasync") == 0) 645 fsflags &= ~MNT_ASYNC; 646 else if (strcmp(opt->name, "noatime") == 0) 647 fsflags |= MNT_NOATIME; 648 else if (strcmp(opt->name, "noclusterr") == 0) 649 fsflags |= MNT_NOCLUSTERR; 650 else if (strcmp(opt->name, "noclusterw") == 0) 651 fsflags |= MNT_NOCLUSTERW; 652 else if (strcmp(opt->name, "noexec") == 0) 653 fsflags |= MNT_NOEXEC; 654 else if (strcmp(opt->name, "nosuid") == 0) 655 fsflags |= MNT_NOSUID; 656 else if (strcmp(opt->name, "nosymfollow") == 0) 657 fsflags |= MNT_NOSYMFOLLOW; 658 else if (strcmp(opt->name, "noro") == 0) { 659 fsflags &= ~MNT_RDONLY; 660 has_noro = 1; 661 } 662 else if (strcmp(opt->name, "rw") == 0) { 663 fsflags &= ~MNT_RDONLY; 664 has_rw = 1; 665 } 666 else if (strcmp(opt->name, "ro") == 0 || 667 strcmp(opt->name, "rdonly") == 0) 668 fsflags |= MNT_RDONLY; 669 else if (strcmp(opt->name, "snapshot") == 0) 670 fsflags |= MNT_SNAPSHOT; 671 else if (strcmp(opt->name, "suiddir") == 0) 672 fsflags |= MNT_SUIDDIR; 673 else if (strcmp(opt->name, "sync") == 0) 674 fsflags |= MNT_SYNCHRONOUS; 675 else if (strcmp(opt->name, "union") == 0) 676 fsflags |= MNT_UNION; 677 } 678 679 /* 680 * If "rw" was specified as a mount option, and we 681 * are trying to update a mount-point from "ro" to "rw", 682 * we need a mount option "noro", since in vfs_mergeopts(), 683 * "noro" will cancel "ro", but "rw" will not do anything. 684 */ 685 if (has_rw && !has_noro) { 686 noro_opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK); 687 noro_opt->name = strdup("noro", M_MOUNT); 688 noro_opt->value = NULL; 689 noro_opt->len = 0; 690 TAILQ_INSERT_TAIL(optlist, noro_opt, link); 691 } 692 693 /* 694 * Be ultra-paranoid about making sure the type and fspath 695 * variables will fit in our mp buffers, including the 696 * terminating NUL. 697 */ 698 if (fstypelen >= MFSNAMELEN - 1 || fspathlen >= MNAMELEN - 1) { 699 error = ENAMETOOLONG; 700 goto bail; 701 } 702 703 mtx_lock(&Giant); 704 error = vfs_domount(td, fstype, fspath, fsflags, optlist); 705 mtx_unlock(&Giant); 706 bail: 707 /* copyout the errmsg */ 708 if (errmsg_pos != -1 && ((2 * errmsg_pos + 1) < fsoptions->uio_iovcnt) 709 && errmsg_len > 0 && errmsg != NULL) { 710 if (fsoptions->uio_segflg == UIO_SYSSPACE) { 711 bcopy(errmsg, 712 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_base, 713 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_len); 714 } else { 715 copyout(errmsg, 716 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_base, 717 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_len); 718 } 719 } 720 721 if (error != 0) 722 vfs_freeopts(optlist); 723 return (error); 724 } 725 726 /* 727 * --------------------------------------------------------------------- 728 * Old mount API. 729 */ 730 #ifndef _SYS_SYSPROTO_H_ 731 struct mount_args { 732 char *type; 733 char *path; 734 int flags; 735 caddr_t data; 736 }; 737 #endif 738 /* ARGSUSED */ 739 int 740 mount(td, uap) 741 struct thread *td; 742 struct mount_args /* { 743 char *type; 744 char *path; 745 int flags; 746 caddr_t data; 747 } */ *uap; 748 { 749 char *fstype; 750 struct vfsconf *vfsp = NULL; 751 struct mntarg *ma = NULL; 752 int error; 753 754 AUDIT_ARG(fflags, uap->flags); 755 756 /* Kick out MNT_ROOTFS early as it is legal internally */ 757 uap->flags &= ~MNT_ROOTFS; 758 759 fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK); 760 error = copyinstr(uap->type, fstype, MFSNAMELEN, NULL); 761 if (error) { 762 free(fstype, M_TEMP); 763 return (error); 764 } 765 766 AUDIT_ARG(text, fstype); 767 mtx_lock(&Giant); 768 vfsp = vfs_byname_kld(fstype, td, &error); 769 free(fstype, M_TEMP); 770 if (vfsp == NULL) { 771 mtx_unlock(&Giant); 772 return (ENOENT); 773 } 774 if (vfsp->vfc_vfsops->vfs_cmount == NULL) { 775 mtx_unlock(&Giant); 776 return (EOPNOTSUPP); 777 } 778 779 ma = mount_argsu(ma, "fstype", uap->type, MNAMELEN); 780 ma = mount_argsu(ma, "fspath", uap->path, MNAMELEN); 781 ma = mount_argb(ma, uap->flags & MNT_RDONLY, "noro"); 782 ma = mount_argb(ma, !(uap->flags & MNT_NOSUID), "nosuid"); 783 ma = mount_argb(ma, !(uap->flags & MNT_NOEXEC), "noexec"); 784 785 error = vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, uap->flags, td); 786 mtx_unlock(&Giant); 787 return (error); 788 } 789 790 791 /* 792 * vfs_domount(): actually attempt a filesystem mount. 793 */ 794 static int 795 vfs_domount( 796 struct thread *td, /* Calling thread. */ 797 const char *fstype, /* Filesystem type. */ 798 char *fspath, /* Mount path. */ 799 int fsflags, /* Flags common to all filesystems. */ 800 void *fsdata /* Options local to the filesystem. */ 801 ) 802 { 803 struct vnode *vp; 804 struct mount *mp; 805 struct vfsconf *vfsp; 806 struct export_args export; 807 int error, flag = 0; 808 struct vattr va; 809 struct nameidata nd; 810 811 mtx_assert(&Giant, MA_OWNED); 812 /* 813 * Be ultra-paranoid about making sure the type and fspath 814 * variables will fit in our mp buffers, including the 815 * terminating NUL. 816 */ 817 if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN) 818 return (ENAMETOOLONG); 819 820 if (jailed(td->td_ucred)) 821 return (EPERM); 822 if (usermount == 0) { 823 if ((error = priv_check(td, PRIV_VFS_MOUNT)) != 0) 824 return (error); 825 } 826 827 /* 828 * Do not allow NFS export or MNT_SUIDDIR by unprivileged users. 829 */ 830 if (fsflags & MNT_EXPORTED) { 831 error = priv_check(td, PRIV_VFS_MOUNT_EXPORTED); 832 if (error) 833 return (error); 834 } 835 if (fsflags & MNT_SUIDDIR) { 836 error = priv_check(td, PRIV_VFS_MOUNT_SUIDDIR); 837 if (error) 838 return (error); 839 840 } 841 /* 842 * Silently enforce MNT_NOSUID and MNT_USER for unprivileged users. 843 */ 844 if ((fsflags & (MNT_NOSUID | MNT_USER)) != (MNT_NOSUID | MNT_USER)) { 845 if (priv_check(td, PRIV_VFS_MOUNT_NONUSER) != 0) 846 fsflags |= MNT_NOSUID | MNT_USER; 847 } 848 849 /* Load KLDs before we lock the covered vnode to avoid reversals. */ 850 vfsp = NULL; 851 if ((fsflags & MNT_UPDATE) == 0) { 852 /* Don't try to load KLDs if we're mounting the root. */ 853 if (fsflags & MNT_ROOTFS) 854 vfsp = vfs_byname(fstype); 855 else 856 vfsp = vfs_byname_kld(fstype, td, &error); 857 if (vfsp == NULL) 858 return (ENODEV); 859 } 860 /* 861 * Get vnode to be covered 862 */ 863 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_SYSSPACE, 864 fspath, td); 865 if ((error = namei(&nd)) != 0) 866 return (error); 867 NDFREE(&nd, NDF_ONLY_PNBUF); 868 vp = nd.ni_vp; 869 if (fsflags & MNT_UPDATE) { 870 if ((vp->v_vflag & VV_ROOT) == 0) { 871 vput(vp); 872 return (EINVAL); 873 } 874 mp = vp->v_mount; 875 MNT_ILOCK(mp); 876 flag = mp->mnt_flag; 877 /* 878 * We only allow the filesystem to be reloaded if it 879 * is currently mounted read-only. 880 */ 881 if ((fsflags & MNT_RELOAD) && 882 ((mp->mnt_flag & MNT_RDONLY) == 0)) { 883 MNT_IUNLOCK(mp); 884 vput(vp); 885 return (EOPNOTSUPP); /* Needs translation */ 886 } 887 MNT_IUNLOCK(mp); 888 /* 889 * Only privileged root, or (if MNT_USER is set) the user that 890 * did the original mount is permitted to update it. 891 */ 892 error = vfs_suser(mp, td); 893 if (error) { 894 vput(vp); 895 return (error); 896 } 897 if (vfs_busy(mp, LK_NOWAIT, 0, td)) { 898 vput(vp); 899 return (EBUSY); 900 } 901 VI_LOCK(vp); 902 if ((vp->v_iflag & VI_MOUNT) != 0 || 903 vp->v_mountedhere != NULL) { 904 VI_UNLOCK(vp); 905 vfs_unbusy(mp, td); 906 vput(vp); 907 return (EBUSY); 908 } 909 vp->v_iflag |= VI_MOUNT; 910 VI_UNLOCK(vp); 911 MNT_ILOCK(mp); 912 mp->mnt_flag |= fsflags & 913 (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT | MNT_ROOTFS); 914 MNT_IUNLOCK(mp); 915 VOP_UNLOCK(vp, 0, td); 916 mp->mnt_optnew = fsdata; 917 vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt); 918 } else { 919 /* 920 * If the user is not root, ensure that they own the directory 921 * onto which we are attempting to mount. 922 */ 923 error = VOP_GETATTR(vp, &va, td->td_ucred, td); 924 if (error) { 925 vput(vp); 926 return (error); 927 } 928 if (va.va_uid != td->td_ucred->cr_uid) { 929 error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN, 930 SUSER_ALLOWJAIL); 931 if (error) { 932 vput(vp); 933 return (error); 934 } 935 } 936 error = vinvalbuf(vp, V_SAVE, td, 0, 0); 937 if (error != 0) { 938 vput(vp); 939 return (error); 940 } 941 if (vp->v_type != VDIR) { 942 vput(vp); 943 return (ENOTDIR); 944 } 945 VI_LOCK(vp); 946 if ((vp->v_iflag & VI_MOUNT) != 0 || 947 vp->v_mountedhere != NULL) { 948 VI_UNLOCK(vp); 949 vput(vp); 950 return (EBUSY); 951 } 952 vp->v_iflag |= VI_MOUNT; 953 VI_UNLOCK(vp); 954 955 /* 956 * Allocate and initialize the filesystem. 957 */ 958 mp = vfs_mount_alloc(vp, vfsp, fspath, td); 959 VOP_UNLOCK(vp, 0, td); 960 961 /* XXXMAC: pass to vfs_mount_alloc? */ 962 mp->mnt_optnew = fsdata; 963 } 964 965 /* 966 * Set the mount level flags. 967 */ 968 MNT_ILOCK(mp); 969 mp->mnt_flag = (mp->mnt_flag & ~MNT_UPDATEMASK) | 970 (fsflags & (MNT_UPDATEMASK | MNT_FORCE | MNT_ROOTFS | 971 MNT_RDONLY)); 972 if ((mp->mnt_flag & MNT_ASYNC) == 0) 973 mp->mnt_kern_flag &= ~MNTK_ASYNC; 974 MNT_IUNLOCK(mp); 975 /* 976 * Mount the filesystem. 977 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they 978 * get. No freeing of cn_pnbuf. 979 */ 980 error = VFS_MOUNT(mp, td); 981 982 /* 983 * Process the export option only if we are 984 * updating mount options. 985 */ 986 if (!error && (fsflags & MNT_UPDATE)) { 987 if (vfs_copyopt(mp->mnt_optnew, "export", &export, 988 sizeof(export)) == 0) 989 error = vfs_export(mp, &export); 990 } 991 992 if (!error) { 993 if (mp->mnt_opt != NULL) 994 vfs_freeopts(mp->mnt_opt); 995 mp->mnt_opt = mp->mnt_optnew; 996 (void)VFS_STATFS(mp, &mp->mnt_stat, td); 997 } 998 /* 999 * Prevent external consumers of mount options from reading 1000 * mnt_optnew. 1001 */ 1002 mp->mnt_optnew = NULL; 1003 if (mp->mnt_flag & MNT_UPDATE) { 1004 MNT_ILOCK(mp); 1005 if (error) 1006 mp->mnt_flag = (mp->mnt_flag & MNT_QUOTA) | 1007 (flag & ~MNT_QUOTA); 1008 else 1009 mp->mnt_flag &= ~(MNT_UPDATE | MNT_RELOAD | 1010 MNT_FORCE | MNT_SNAPSHOT); 1011 if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0) 1012 mp->mnt_kern_flag |= MNTK_ASYNC; 1013 else 1014 mp->mnt_kern_flag &= ~MNTK_ASYNC; 1015 MNT_IUNLOCK(mp); 1016 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 1017 if (mp->mnt_syncer == NULL) 1018 error = vfs_allocate_syncvnode(mp); 1019 } else { 1020 if (mp->mnt_syncer != NULL) 1021 vrele(mp->mnt_syncer); 1022 mp->mnt_syncer = NULL; 1023 } 1024 vfs_unbusy(mp, td); 1025 VI_LOCK(vp); 1026 vp->v_iflag &= ~VI_MOUNT; 1027 VI_UNLOCK(vp); 1028 vrele(vp); 1029 return (error); 1030 } 1031 MNT_ILOCK(mp); 1032 if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0) 1033 mp->mnt_kern_flag |= MNTK_ASYNC; 1034 else 1035 mp->mnt_kern_flag &= ~MNTK_ASYNC; 1036 MNT_IUNLOCK(mp); 1037 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1038 /* 1039 * Put the new filesystem on the mount list after root. 1040 */ 1041 cache_purge(vp); 1042 if (!error) { 1043 struct vnode *newdp; 1044 1045 VI_LOCK(vp); 1046 vp->v_iflag &= ~VI_MOUNT; 1047 VI_UNLOCK(vp); 1048 vp->v_mountedhere = mp; 1049 mtx_lock(&mountlist_mtx); 1050 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); 1051 mtx_unlock(&mountlist_mtx); 1052 vfs_event_signal(NULL, VQ_MOUNT, 0); 1053 if (VFS_ROOT(mp, LK_EXCLUSIVE, &newdp, td)) 1054 panic("mount: lost mount"); 1055 mountcheckdirs(vp, newdp); 1056 vput(newdp); 1057 VOP_UNLOCK(vp, 0, td); 1058 if ((mp->mnt_flag & MNT_RDONLY) == 0) 1059 error = vfs_allocate_syncvnode(mp); 1060 vfs_unbusy(mp, td); 1061 if (error) 1062 vrele(vp); 1063 } else { 1064 VI_LOCK(vp); 1065 vp->v_iflag &= ~VI_MOUNT; 1066 VI_UNLOCK(vp); 1067 vfs_unbusy(mp, td); 1068 vfs_mount_destroy(mp); 1069 vput(vp); 1070 } 1071 return (error); 1072 } 1073 1074 /* 1075 * --------------------------------------------------------------------- 1076 * Unmount a filesystem. 1077 * 1078 * Note: unmount takes a path to the vnode mounted on as argument, 1079 * not special file (as before). 1080 */ 1081 #ifndef _SYS_SYSPROTO_H_ 1082 struct unmount_args { 1083 char *path; 1084 int flags; 1085 }; 1086 #endif 1087 /* ARGSUSED */ 1088 int 1089 unmount(td, uap) 1090 struct thread *td; 1091 register struct unmount_args /* { 1092 char *path; 1093 int flags; 1094 } */ *uap; 1095 { 1096 struct mount *mp; 1097 char *pathbuf; 1098 int error, id0, id1; 1099 1100 if (jailed(td->td_ucred)) 1101 return (EPERM); 1102 if (usermount == 0) { 1103 error = priv_check(td, PRIV_VFS_UNMOUNT); 1104 if (error) 1105 return (error); 1106 } 1107 1108 pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK); 1109 error = copyinstr(uap->path, pathbuf, MNAMELEN, NULL); 1110 if (error) { 1111 free(pathbuf, M_TEMP); 1112 return (error); 1113 } 1114 AUDIT_ARG(upath, td, pathbuf, ARG_UPATH1); 1115 mtx_lock(&Giant); 1116 if (uap->flags & MNT_BYFSID) { 1117 /* Decode the filesystem ID. */ 1118 if (sscanf(pathbuf, "FSID:%d:%d", &id0, &id1) != 2) { 1119 mtx_unlock(&Giant); 1120 free(pathbuf, M_TEMP); 1121 return (EINVAL); 1122 } 1123 1124 mtx_lock(&mountlist_mtx); 1125 TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { 1126 if (mp->mnt_stat.f_fsid.val[0] == id0 && 1127 mp->mnt_stat.f_fsid.val[1] == id1) 1128 break; 1129 } 1130 mtx_unlock(&mountlist_mtx); 1131 } else { 1132 mtx_lock(&mountlist_mtx); 1133 TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { 1134 if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0) 1135 break; 1136 } 1137 mtx_unlock(&mountlist_mtx); 1138 } 1139 free(pathbuf, M_TEMP); 1140 if (mp == NULL) { 1141 /* 1142 * Previously we returned ENOENT for a nonexistent path and 1143 * EINVAL for a non-mountpoint. We cannot tell these apart 1144 * now, so in the !MNT_BYFSID case return the more likely 1145 * EINVAL for compatibility. 1146 */ 1147 mtx_unlock(&Giant); 1148 return ((uap->flags & MNT_BYFSID) ? ENOENT : EINVAL); 1149 } 1150 1151 /* 1152 * Don't allow unmounting the root filesystem. 1153 */ 1154 if (mp->mnt_flag & MNT_ROOTFS) { 1155 mtx_unlock(&Giant); 1156 return (EINVAL); 1157 } 1158 error = dounmount(mp, uap->flags, td); 1159 mtx_unlock(&Giant); 1160 return (error); 1161 } 1162 1163 /* 1164 * Do the actual filesystem unmount. 1165 */ 1166 int 1167 dounmount(mp, flags, td) 1168 struct mount *mp; 1169 int flags; 1170 struct thread *td; 1171 { 1172 struct vnode *coveredvp, *fsrootvp; 1173 int error; 1174 int async_flag; 1175 int mnt_gen_r; 1176 1177 mtx_assert(&Giant, MA_OWNED); 1178 1179 if ((coveredvp = mp->mnt_vnodecovered) != NULL) { 1180 mnt_gen_r = mp->mnt_gen; 1181 VI_LOCK(coveredvp); 1182 vholdl(coveredvp); 1183 error = vn_lock(coveredvp, LK_EXCLUSIVE | LK_INTERLOCK, td); 1184 vdrop(coveredvp); 1185 /* 1186 * Check for mp being unmounted while waiting for the 1187 * covered vnode lock. 1188 */ 1189 if (error) 1190 return (error); 1191 if (coveredvp->v_mountedhere != mp || 1192 coveredvp->v_mountedhere->mnt_gen != mnt_gen_r) { 1193 VOP_UNLOCK(coveredvp, 0, td); 1194 return (EBUSY); 1195 } 1196 } 1197 /* 1198 * Only privileged root, or (if MNT_USER is set) the user that did the 1199 * original mount is permitted to unmount this filesystem. 1200 */ 1201 error = vfs_suser(mp, td); 1202 if (error) { 1203 if (coveredvp) 1204 VOP_UNLOCK(coveredvp, 0, td); 1205 return (error); 1206 } 1207 1208 MNT_ILOCK(mp); 1209 if (mp->mnt_kern_flag & MNTK_UNMOUNT) { 1210 MNT_IUNLOCK(mp); 1211 if (coveredvp) 1212 VOP_UNLOCK(coveredvp, 0, td); 1213 return (EBUSY); 1214 } 1215 mp->mnt_kern_flag |= MNTK_UNMOUNT; 1216 /* Allow filesystems to detect that a forced unmount is in progress. */ 1217 if (flags & MNT_FORCE) 1218 mp->mnt_kern_flag |= MNTK_UNMOUNTF; 1219 error = lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK | 1220 ((flags & MNT_FORCE) ? 0 : LK_NOWAIT), MNT_MTX(mp), td); 1221 if (error) { 1222 MNT_ILOCK(mp); 1223 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF); 1224 if (mp->mnt_kern_flag & MNTK_MWAIT) 1225 wakeup(mp); 1226 MNT_IUNLOCK(mp); 1227 if (coveredvp) 1228 VOP_UNLOCK(coveredvp, 0, td); 1229 return (error); 1230 } 1231 vn_start_write(NULL, &mp, V_WAIT); 1232 1233 if (mp->mnt_flag & MNT_EXPUBLIC) 1234 vfs_setpublicfs(NULL, NULL, NULL); 1235 1236 vfs_msync(mp, MNT_WAIT); 1237 MNT_ILOCK(mp); 1238 async_flag = mp->mnt_flag & MNT_ASYNC; 1239 mp->mnt_flag &= ~MNT_ASYNC; 1240 mp->mnt_kern_flag &= ~MNTK_ASYNC; 1241 MNT_IUNLOCK(mp); 1242 cache_purgevfs(mp); /* remove cache entries for this file sys */ 1243 if (mp->mnt_syncer != NULL) 1244 vrele(mp->mnt_syncer); 1245 /* 1246 * For forced unmounts, move process cdir/rdir refs on the fs root 1247 * vnode to the covered vnode. For non-forced unmounts we want 1248 * such references to cause an EBUSY error. 1249 */ 1250 if ((flags & MNT_FORCE) && 1251 VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp, td) == 0) { 1252 if (mp->mnt_vnodecovered != NULL) 1253 mountcheckdirs(fsrootvp, mp->mnt_vnodecovered); 1254 if (fsrootvp == rootvnode) { 1255 vrele(rootvnode); 1256 rootvnode = NULL; 1257 } 1258 vput(fsrootvp); 1259 } 1260 if (((mp->mnt_flag & MNT_RDONLY) || 1261 (error = VFS_SYNC(mp, MNT_WAIT, td)) == 0) || 1262 (flags & MNT_FORCE)) { 1263 error = VFS_UNMOUNT(mp, flags, td); 1264 } 1265 vn_finished_write(mp); 1266 if (error) { 1267 /* Undo cdir/rdir and rootvnode changes made above. */ 1268 if ((flags & MNT_FORCE) && 1269 VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp, td) == 0) { 1270 if (mp->mnt_vnodecovered != NULL) 1271 mountcheckdirs(mp->mnt_vnodecovered, fsrootvp); 1272 if (rootvnode == NULL) { 1273 rootvnode = fsrootvp; 1274 vref(rootvnode); 1275 } 1276 vput(fsrootvp); 1277 } 1278 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL) 1279 (void) vfs_allocate_syncvnode(mp); 1280 MNT_ILOCK(mp); 1281 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF); 1282 mp->mnt_flag |= async_flag; 1283 if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0) 1284 mp->mnt_kern_flag |= MNTK_ASYNC; 1285 lockmgr(&mp->mnt_lock, LK_RELEASE, NULL, td); 1286 if (mp->mnt_kern_flag & MNTK_MWAIT) 1287 wakeup(mp); 1288 MNT_IUNLOCK(mp); 1289 if (coveredvp) 1290 VOP_UNLOCK(coveredvp, 0, td); 1291 return (error); 1292 } 1293 mtx_lock(&mountlist_mtx); 1294 TAILQ_REMOVE(&mountlist, mp, mnt_list); 1295 mtx_unlock(&mountlist_mtx); 1296 if (coveredvp != NULL) { 1297 coveredvp->v_mountedhere = NULL; 1298 vput(coveredvp); 1299 } 1300 vfs_event_signal(NULL, VQ_UNMOUNT, 0); 1301 lockmgr(&mp->mnt_lock, LK_RELEASE, NULL, td); 1302 vfs_mount_destroy(mp); 1303 return (0); 1304 } 1305 1306 /* 1307 * --------------------------------------------------------------------- 1308 * Mounting of root filesystem 1309 * 1310 */ 1311 1312 struct root_hold_token { 1313 const char *who; 1314 LIST_ENTRY(root_hold_token) list; 1315 }; 1316 1317 static LIST_HEAD(, root_hold_token) root_holds = 1318 LIST_HEAD_INITIALIZER(&root_holds); 1319 1320 struct root_hold_token * 1321 root_mount_hold(const char *identifier) 1322 { 1323 struct root_hold_token *h; 1324 1325 h = malloc(sizeof *h, M_DEVBUF, M_ZERO | M_WAITOK); 1326 h->who = identifier; 1327 mtx_lock(&mountlist_mtx); 1328 LIST_INSERT_HEAD(&root_holds, h, list); 1329 mtx_unlock(&mountlist_mtx); 1330 return (h); 1331 } 1332 1333 void 1334 root_mount_rel(struct root_hold_token *h) 1335 { 1336 1337 mtx_lock(&mountlist_mtx); 1338 LIST_REMOVE(h, list); 1339 wakeup(&root_holds); 1340 mtx_unlock(&mountlist_mtx); 1341 free(h, M_DEVBUF); 1342 } 1343 1344 static void 1345 root_mount_wait(void) 1346 { 1347 struct root_hold_token *h; 1348 1349 for (;;) { 1350 DROP_GIANT(); 1351 g_waitidle(); 1352 PICKUP_GIANT(); 1353 mtx_lock(&mountlist_mtx); 1354 if (LIST_EMPTY(&root_holds)) { 1355 mtx_unlock(&mountlist_mtx); 1356 break; 1357 } 1358 printf("Root mount waiting for:"); 1359 LIST_FOREACH(h, &root_holds, list) 1360 printf(" %s", h->who); 1361 printf("\n"); 1362 msleep(&root_holds, &mountlist_mtx, PZERO | PDROP, "roothold", 1363 hz); 1364 } 1365 } 1366 1367 static void 1368 set_rootvnode(struct thread *td) 1369 { 1370 struct proc *p; 1371 1372 if (VFS_ROOT(TAILQ_FIRST(&mountlist), LK_EXCLUSIVE, &rootvnode, td)) 1373 panic("Cannot find root vnode"); 1374 1375 p = td->td_proc; 1376 FILEDESC_LOCK(p->p_fd); 1377 1378 if (p->p_fd->fd_cdir != NULL) 1379 vrele(p->p_fd->fd_cdir); 1380 p->p_fd->fd_cdir = rootvnode; 1381 VREF(rootvnode); 1382 1383 if (p->p_fd->fd_rdir != NULL) 1384 vrele(p->p_fd->fd_rdir); 1385 p->p_fd->fd_rdir = rootvnode; 1386 VREF(rootvnode); 1387 1388 FILEDESC_UNLOCK(p->p_fd); 1389 1390 VOP_UNLOCK(rootvnode, 0, td); 1391 } 1392 1393 /* 1394 * Mount /devfs as our root filesystem, but do not put it on the mountlist 1395 * yet. Create a /dev -> / symlink so that absolute pathnames will lookup. 1396 */ 1397 1398 static void 1399 devfs_first(void) 1400 { 1401 struct thread *td = curthread; 1402 struct vfsoptlist *opts; 1403 struct vfsconf *vfsp; 1404 struct mount *mp = NULL; 1405 int error; 1406 1407 vfsp = vfs_byname("devfs"); 1408 KASSERT(vfsp != NULL, ("Could not find devfs by name")); 1409 if (vfsp == NULL) 1410 return; 1411 1412 mp = vfs_mount_alloc(NULLVP, vfsp, "/dev", td); 1413 1414 error = VFS_MOUNT(mp, td); 1415 KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error)); 1416 if (error) 1417 return; 1418 1419 opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); 1420 TAILQ_INIT(opts); 1421 mp->mnt_opt = opts; 1422 1423 mtx_lock(&mountlist_mtx); 1424 TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); 1425 mtx_unlock(&mountlist_mtx); 1426 1427 set_rootvnode(td); 1428 1429 error = kern_symlink(td, "/", "dev", UIO_SYSSPACE); 1430 if (error) 1431 printf("kern_symlink /dev -> / returns %d\n", error); 1432 } 1433 1434 /* 1435 * Surgically move our devfs to be mounted on /dev. 1436 */ 1437 1438 static void 1439 devfs_fixup(struct thread *td) 1440 { 1441 struct nameidata nd; 1442 int error; 1443 struct vnode *vp, *dvp; 1444 struct mount *mp; 1445 1446 /* Remove our devfs mount from the mountlist and purge the cache */ 1447 mtx_lock(&mountlist_mtx); 1448 mp = TAILQ_FIRST(&mountlist); 1449 TAILQ_REMOVE(&mountlist, mp, mnt_list); 1450 mtx_unlock(&mountlist_mtx); 1451 cache_purgevfs(mp); 1452 1453 VFS_ROOT(mp, LK_EXCLUSIVE, &dvp, td); 1454 VI_LOCK(dvp); 1455 dvp->v_iflag &= ~VI_MOUNT; 1456 dvp->v_mountedhere = NULL; 1457 VI_UNLOCK(dvp); 1458 1459 /* Set up the real rootvnode, and purge the cache */ 1460 TAILQ_FIRST(&mountlist)->mnt_vnodecovered = NULL; 1461 set_rootvnode(td); 1462 cache_purgevfs(rootvnode->v_mount); 1463 1464 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, "/dev", td); 1465 error = namei(&nd); 1466 if (error) { 1467 printf("Lookup of /dev for devfs, error: %d\n", error); 1468 return; 1469 } 1470 NDFREE(&nd, NDF_ONLY_PNBUF); 1471 vp = nd.ni_vp; 1472 if (vp->v_type != VDIR) { 1473 vput(vp); 1474 } 1475 error = vinvalbuf(vp, V_SAVE, td, 0, 0); 1476 if (error) { 1477 vput(vp); 1478 } 1479 cache_purge(vp); 1480 mp->mnt_vnodecovered = vp; 1481 vp->v_mountedhere = mp; 1482 mtx_lock(&mountlist_mtx); 1483 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); 1484 mtx_unlock(&mountlist_mtx); 1485 VOP_UNLOCK(vp, 0, td); 1486 vput(dvp); 1487 vfs_unbusy(mp, td); 1488 1489 /* Unlink the no longer needed /dev/dev -> / symlink */ 1490 kern_unlink(td, "/dev/dev", UIO_SYSSPACE); 1491 } 1492 1493 /* 1494 * Report errors during filesystem mounting. 1495 */ 1496 void 1497 vfs_mount_error(struct mount *mp, const char *fmt, ...) 1498 { 1499 struct vfsoptlist *moptlist = mp->mnt_optnew; 1500 va_list ap; 1501 int error, len; 1502 char *errmsg; 1503 1504 error = vfs_getopt(moptlist, "errmsg", (void **)&errmsg, &len); 1505 if (error || errmsg == NULL || len <= 0) 1506 return; 1507 1508 va_start(ap, fmt); 1509 vsnprintf(errmsg, (size_t)len, fmt, ap); 1510 va_end(ap); 1511 } 1512 1513 /* 1514 * Find and mount the root filesystem 1515 */ 1516 void 1517 vfs_mountroot(void) 1518 { 1519 char *cp; 1520 int error, i, asked = 0; 1521 1522 root_mount_wait(); 1523 1524 mount_zone = uma_zcreate("Mountpoints", sizeof(struct mount), 1525 NULL, NULL, mount_init, mount_fini, 1526 UMA_ALIGN_PTR, UMA_ZONE_NOFREE); 1527 devfs_first(); 1528 1529 /* 1530 * We are booted with instructions to prompt for the root filesystem. 1531 */ 1532 if (boothowto & RB_ASKNAME) { 1533 if (!vfs_mountroot_ask()) 1534 return; 1535 asked = 1; 1536 } 1537 1538 /* 1539 * The root filesystem information is compiled in, and we are 1540 * booted with instructions to use it. 1541 */ 1542 if (ctrootdevname != NULL && (boothowto & RB_DFLTROOT)) { 1543 if (!vfs_mountroot_try(ctrootdevname)) 1544 return; 1545 ctrootdevname = NULL; 1546 } 1547 1548 /* 1549 * We've been given the generic "use CDROM as root" flag. This is 1550 * necessary because one media may be used in many different 1551 * devices, so we need to search for them. 1552 */ 1553 if (boothowto & RB_CDROM) { 1554 for (i = 0; cdrom_rootdevnames[i] != NULL; i++) { 1555 if (!vfs_mountroot_try(cdrom_rootdevnames[i])) 1556 return; 1557 } 1558 } 1559 1560 /* 1561 * Try to use the value read by the loader from /etc/fstab, or 1562 * supplied via some other means. This is the preferred 1563 * mechanism. 1564 */ 1565 cp = getenv("vfs.root.mountfrom"); 1566 if (cp != NULL) { 1567 error = vfs_mountroot_try(cp); 1568 freeenv(cp); 1569 if (!error) 1570 return; 1571 } 1572 1573 /* 1574 * Try values that may have been computed by code during boot 1575 */ 1576 if (!vfs_mountroot_try(rootdevnames[0])) 1577 return; 1578 if (!vfs_mountroot_try(rootdevnames[1])) 1579 return; 1580 1581 /* 1582 * If we (still) have a compiled-in default, try it. 1583 */ 1584 if (ctrootdevname != NULL) 1585 if (!vfs_mountroot_try(ctrootdevname)) 1586 return; 1587 /* 1588 * Everything so far has failed, prompt on the console if we haven't 1589 * already tried that. 1590 */ 1591 if (!asked) 1592 if (!vfs_mountroot_ask()) 1593 return; 1594 1595 panic("Root mount failed, startup aborted."); 1596 } 1597 1598 /* 1599 * Mount (mountfrom) as the root filesystem. 1600 */ 1601 static int 1602 vfs_mountroot_try(const char *mountfrom) 1603 { 1604 struct mount *mp; 1605 char *vfsname, *path; 1606 time_t timebase; 1607 int error; 1608 char patt[32]; 1609 1610 vfsname = NULL; 1611 path = NULL; 1612 mp = NULL; 1613 error = EINVAL; 1614 1615 if (mountfrom == NULL) 1616 return (error); /* don't complain */ 1617 printf("Trying to mount root from %s\n", mountfrom); 1618 1619 /* parse vfs name and path */ 1620 vfsname = malloc(MFSNAMELEN, M_MOUNT, M_WAITOK); 1621 path = malloc(MNAMELEN, M_MOUNT, M_WAITOK); 1622 vfsname[0] = path[0] = 0; 1623 sprintf(patt, "%%%d[a-z0-9]:%%%ds", MFSNAMELEN, MNAMELEN); 1624 if (sscanf(mountfrom, patt, vfsname, path) < 1) 1625 goto out; 1626 1627 if (path[0] == '\0') 1628 strcpy(path, ROOTNAME); 1629 1630 error = kernel_vmount( 1631 MNT_RDONLY | MNT_ROOTFS, 1632 "fstype", vfsname, 1633 "fspath", "/", 1634 "from", path, 1635 NULL); 1636 if (error == 0) { 1637 /* 1638 * We mount devfs prior to mounting the / FS, so the first 1639 * entry will typically be devfs. 1640 */ 1641 mp = TAILQ_FIRST(&mountlist); 1642 KASSERT(mp != NULL, ("%s: mountlist is empty", __func__)); 1643 1644 /* 1645 * Iterate over all currently mounted file systems and use 1646 * the time stamp found to check and/or initialize the RTC. 1647 * Typically devfs has no time stamp and the only other FS 1648 * is the actual / FS. 1649 * Call inittodr() only once and pass it the largest of the 1650 * timestamps we encounter. 1651 */ 1652 timebase = 0; 1653 do { 1654 if (mp->mnt_time > timebase) 1655 timebase = mp->mnt_time; 1656 mp = TAILQ_NEXT(mp, mnt_list); 1657 } while (mp != NULL); 1658 inittodr(timebase); 1659 1660 devfs_fixup(curthread); 1661 } 1662 out: 1663 free(path, M_MOUNT); 1664 free(vfsname, M_MOUNT); 1665 return (error); 1666 } 1667 1668 /* 1669 * --------------------------------------------------------------------- 1670 * Interactive root filesystem selection code. 1671 */ 1672 1673 static int 1674 vfs_mountroot_ask(void) 1675 { 1676 char name[128]; 1677 1678 for(;;) { 1679 printf("\nManual root filesystem specification:\n"); 1680 printf(" <fstype>:<device> Mount <device> using filesystem <fstype>\n"); 1681 #if defined(__amd64__) || defined(__i386__) || defined(__ia64__) 1682 printf(" eg. ufs:da0s1a\n"); 1683 #else 1684 printf(" eg. ufs:/dev/da0a\n"); 1685 #endif 1686 printf(" ? List valid disk boot devices\n"); 1687 printf(" <empty line> Abort manual input\n"); 1688 printf("\nmountroot> "); 1689 gets(name, sizeof(name), 1); 1690 if (name[0] == '\0') 1691 return (1); 1692 if (name[0] == '?') { 1693 printf("\nList of GEOM managed disk devices:\n "); 1694 g_dev_print(); 1695 continue; 1696 } 1697 if (!vfs_mountroot_try(name)) 1698 return (0); 1699 } 1700 } 1701 1702 /* 1703 * --------------------------------------------------------------------- 1704 * Functions for querying mount options/arguments from filesystems. 1705 */ 1706 1707 /* 1708 * Check that no unknown options are given 1709 */ 1710 int 1711 vfs_filteropt(struct vfsoptlist *opts, const char **legal) 1712 { 1713 struct vfsopt *opt; 1714 const char **t, *p; 1715 1716 1717 TAILQ_FOREACH(opt, opts, link) { 1718 p = opt->name; 1719 if (p[0] == 'n' && p[1] == 'o') 1720 p += 2; 1721 for(t = global_opts; *t != NULL; t++) 1722 if (!strcmp(*t, p)) 1723 break; 1724 if (*t != NULL) 1725 continue; 1726 for(t = legal; *t != NULL; t++) 1727 if (!strcmp(*t, p)) 1728 break; 1729 if (*t != NULL) 1730 continue; 1731 printf("mount option <%s> is unknown\n", p); 1732 return (EINVAL); 1733 } 1734 return (0); 1735 } 1736 1737 /* 1738 * Get a mount option by its name. 1739 * 1740 * Return 0 if the option was found, ENOENT otherwise. 1741 * If len is non-NULL it will be filled with the length 1742 * of the option. If buf is non-NULL, it will be filled 1743 * with the address of the option. 1744 */ 1745 int 1746 vfs_getopt(opts, name, buf, len) 1747 struct vfsoptlist *opts; 1748 const char *name; 1749 void **buf; 1750 int *len; 1751 { 1752 struct vfsopt *opt; 1753 1754 KASSERT(opts != NULL, ("vfs_getopt: caller passed 'opts' as NULL")); 1755 1756 TAILQ_FOREACH(opt, opts, link) { 1757 if (strcmp(name, opt->name) == 0) { 1758 if (len != NULL) 1759 *len = opt->len; 1760 if (buf != NULL) 1761 *buf = opt->value; 1762 return (0); 1763 } 1764 } 1765 return (ENOENT); 1766 } 1767 1768 static int 1769 vfs_getopt_pos(struct vfsoptlist *opts, const char *name) 1770 { 1771 struct vfsopt *opt; 1772 int i; 1773 1774 if (opts == NULL) 1775 return (-1); 1776 1777 i = 0; 1778 TAILQ_FOREACH(opt, opts, link) { 1779 if (strcmp(name, opt->name) == 0) 1780 return (i); 1781 ++i; 1782 } 1783 return (-1); 1784 } 1785 1786 char * 1787 vfs_getopts(struct vfsoptlist *opts, const char *name, int *error) 1788 { 1789 struct vfsopt *opt; 1790 1791 *error = 0; 1792 TAILQ_FOREACH(opt, opts, link) { 1793 if (strcmp(name, opt->name) != 0) 1794 continue; 1795 if (((char *)opt->value)[opt->len - 1] != '\0') { 1796 *error = EINVAL; 1797 return (NULL); 1798 } 1799 return (opt->value); 1800 } 1801 *error = ENOENT; 1802 return (NULL); 1803 } 1804 1805 int 1806 vfs_flagopt(struct vfsoptlist *opts, const char *name, u_int *w, u_int val) 1807 { 1808 struct vfsopt *opt; 1809 1810 TAILQ_FOREACH(opt, opts, link) { 1811 if (strcmp(name, opt->name) == 0) { 1812 if (w != NULL) 1813 *w |= val; 1814 return (1); 1815 } 1816 } 1817 if (w != NULL) 1818 *w &= ~val; 1819 return (0); 1820 } 1821 1822 int 1823 vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...) 1824 { 1825 va_list ap; 1826 struct vfsopt *opt; 1827 int ret; 1828 1829 KASSERT(opts != NULL, ("vfs_getopt: caller passed 'opts' as NULL")); 1830 1831 TAILQ_FOREACH(opt, opts, link) { 1832 if (strcmp(name, opt->name) != 0) 1833 continue; 1834 if (((char *)opt->value)[opt->len - 1] != '\0') 1835 return (0); 1836 va_start(ap, fmt); 1837 ret = vsscanf(opt->value, fmt, ap); 1838 va_end(ap); 1839 return (ret); 1840 } 1841 return (0); 1842 } 1843 1844 /* 1845 * Find and copy a mount option. 1846 * 1847 * The size of the buffer has to be specified 1848 * in len, if it is not the same length as the 1849 * mount option, EINVAL is returned. 1850 * Returns ENOENT if the option is not found. 1851 */ 1852 int 1853 vfs_copyopt(opts, name, dest, len) 1854 struct vfsoptlist *opts; 1855 const char *name; 1856 void *dest; 1857 int len; 1858 { 1859 struct vfsopt *opt; 1860 1861 KASSERT(opts != NULL, ("vfs_copyopt: caller passed 'opts' as NULL")); 1862 1863 TAILQ_FOREACH(opt, opts, link) { 1864 if (strcmp(name, opt->name) == 0) { 1865 if (len != opt->len) 1866 return (EINVAL); 1867 bcopy(opt->value, dest, opt->len); 1868 return (0); 1869 } 1870 } 1871 return (ENOENT); 1872 } 1873 1874 /* 1875 * This is a helper function for filesystems to traverse their 1876 * vnodes. See MNT_VNODE_FOREACH() in sys/mount.h 1877 */ 1878 1879 struct vnode * 1880 __mnt_vnode_next(struct vnode **mvp, struct mount *mp) 1881 { 1882 struct vnode *vp; 1883 1884 mtx_assert(MNT_MTX(mp), MA_OWNED); 1885 1886 KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch")); 1887 vp = TAILQ_NEXT(*mvp, v_nmntvnodes); 1888 while (vp != NULL && vp->v_type == VMARKER) 1889 vp = TAILQ_NEXT(vp, v_nmntvnodes); 1890 1891 /* Check if we are done */ 1892 if (vp == NULL) { 1893 __mnt_vnode_markerfree(mvp, mp); 1894 return (NULL); 1895 } 1896 TAILQ_REMOVE(&mp->mnt_nvnodelist, *mvp, v_nmntvnodes); 1897 TAILQ_INSERT_AFTER(&mp->mnt_nvnodelist, vp, *mvp, v_nmntvnodes); 1898 return (vp); 1899 } 1900 1901 struct vnode * 1902 __mnt_vnode_first(struct vnode **mvp, struct mount *mp) 1903 { 1904 struct vnode *vp; 1905 1906 mtx_assert(MNT_MTX(mp), MA_OWNED); 1907 1908 vp = TAILQ_FIRST(&mp->mnt_nvnodelist); 1909 while (vp != NULL && vp->v_type == VMARKER) 1910 vp = TAILQ_NEXT(vp, v_nmntvnodes); 1911 1912 /* Check if we are done */ 1913 if (vp == NULL) { 1914 *mvp = NULL; 1915 return (NULL); 1916 } 1917 mp->mnt_holdcnt++; 1918 MNT_IUNLOCK(mp); 1919 *mvp = (struct vnode *) malloc(sizeof(struct vnode), 1920 M_VNODE_MARKER, 1921 M_WAITOK | M_ZERO); 1922 MNT_ILOCK(mp); 1923 (*mvp)->v_type = VMARKER; 1924 1925 vp = TAILQ_FIRST(&mp->mnt_nvnodelist); 1926 while (vp != NULL && vp->v_type == VMARKER) 1927 vp = TAILQ_NEXT(vp, v_nmntvnodes); 1928 1929 /* Check if we are done */ 1930 if (vp == NULL) { 1931 MNT_IUNLOCK(mp); 1932 free(*mvp, M_VNODE_MARKER); 1933 MNT_ILOCK(mp); 1934 *mvp = NULL; 1935 mp->mnt_holdcnt--; 1936 if (mp->mnt_holdcnt == 0 && mp->mnt_holdcntwaiters != 0) 1937 wakeup(&mp->mnt_holdcnt); 1938 return (NULL); 1939 } 1940 mp->mnt_markercnt++; 1941 (*mvp)->v_mount = mp; 1942 TAILQ_INSERT_AFTER(&mp->mnt_nvnodelist, vp, *mvp, v_nmntvnodes); 1943 return (vp); 1944 } 1945 1946 1947 void 1948 __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp) 1949 { 1950 1951 if (*mvp == NULL) 1952 return; 1953 1954 mtx_assert(MNT_MTX(mp), MA_OWNED); 1955 1956 KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch")); 1957 TAILQ_REMOVE(&mp->mnt_nvnodelist, *mvp, v_nmntvnodes); 1958 MNT_IUNLOCK(mp); 1959 free(*mvp, M_VNODE_MARKER); 1960 MNT_ILOCK(mp); 1961 *mvp = NULL; 1962 1963 mp->mnt_markercnt--; 1964 mp->mnt_holdcnt--; 1965 if (mp->mnt_holdcnt == 0 && mp->mnt_holdcntwaiters != 0) 1966 wakeup(&mp->mnt_holdcnt); 1967 } 1968 1969 1970 int 1971 __vfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) 1972 { 1973 int error; 1974 1975 error = mp->mnt_op->vfs_statfs(mp, &mp->mnt_stat, td); 1976 if (sbp != &mp->mnt_stat) 1977 *sbp = mp->mnt_stat; 1978 return (error); 1979 } 1980 1981 void 1982 vfs_mountedfrom(struct mount *mp, const char *from) 1983 { 1984 1985 bzero(mp->mnt_stat.f_mntfromname, sizeof mp->mnt_stat.f_mntfromname); 1986 strlcpy(mp->mnt_stat.f_mntfromname, from, 1987 sizeof mp->mnt_stat.f_mntfromname); 1988 } 1989 1990 /* 1991 * --------------------------------------------------------------------- 1992 * This is the api for building mount args and mounting filesystems from 1993 * inside the kernel. 1994 * 1995 * The API works by accumulation of individual args. First error is 1996 * latched. 1997 * 1998 * XXX: should be documented in new manpage kernel_mount(9) 1999 */ 2000 2001 /* A memory allocation which must be freed when we are done */ 2002 struct mntaarg { 2003 SLIST_ENTRY(mntaarg) next; 2004 }; 2005 2006 /* The header for the mount arguments */ 2007 struct mntarg { 2008 struct iovec *v; 2009 int len; 2010 int error; 2011 SLIST_HEAD(, mntaarg) list; 2012 }; 2013 2014 /* 2015 * Add a boolean argument. 2016 * 2017 * flag is the boolean value. 2018 * name must start with "no". 2019 */ 2020 struct mntarg * 2021 mount_argb(struct mntarg *ma, int flag, const char *name) 2022 { 2023 2024 KASSERT(name[0] == 'n' && name[1] == 'o', 2025 ("mount_argb(...,%s): name must start with 'no'", name)); 2026 2027 return (mount_arg(ma, name + (flag ? 2 : 0), NULL, 0)); 2028 } 2029 2030 /* 2031 * Add an argument printf style 2032 */ 2033 struct mntarg * 2034 mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...) 2035 { 2036 va_list ap; 2037 struct mntaarg *maa; 2038 struct sbuf *sb; 2039 int len; 2040 2041 if (ma == NULL) { 2042 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO); 2043 SLIST_INIT(&ma->list); 2044 } 2045 if (ma->error) 2046 return (ma); 2047 2048 ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2), 2049 M_MOUNT, M_WAITOK); 2050 ma->v[ma->len].iov_base = (void *)(uintptr_t)name; 2051 ma->v[ma->len].iov_len = strlen(name) + 1; 2052 ma->len++; 2053 2054 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 2055 va_start(ap, fmt); 2056 sbuf_vprintf(sb, fmt, ap); 2057 va_end(ap); 2058 sbuf_finish(sb); 2059 len = sbuf_len(sb) + 1; 2060 maa = malloc(sizeof *maa + len, M_MOUNT, M_WAITOK | M_ZERO); 2061 SLIST_INSERT_HEAD(&ma->list, maa, next); 2062 bcopy(sbuf_data(sb), maa + 1, len); 2063 sbuf_delete(sb); 2064 2065 ma->v[ma->len].iov_base = maa + 1; 2066 ma->v[ma->len].iov_len = len; 2067 ma->len++; 2068 2069 return (ma); 2070 } 2071 2072 /* 2073 * Add an argument which is a userland string. 2074 */ 2075 struct mntarg * 2076 mount_argsu(struct mntarg *ma, const char *name, const void *val, int len) 2077 { 2078 struct mntaarg *maa; 2079 char *tbuf; 2080 2081 if (val == NULL) 2082 return (ma); 2083 if (ma == NULL) { 2084 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO); 2085 SLIST_INIT(&ma->list); 2086 } 2087 if (ma->error) 2088 return (ma); 2089 maa = malloc(sizeof *maa + len, M_MOUNT, M_WAITOK | M_ZERO); 2090 SLIST_INSERT_HEAD(&ma->list, maa, next); 2091 tbuf = (void *)(maa + 1); 2092 ma->error = copyinstr(val, tbuf, len, NULL); 2093 return (mount_arg(ma, name, tbuf, -1)); 2094 } 2095 2096 /* 2097 * Plain argument. 2098 * 2099 * If length is -1, use printf. 2100 */ 2101 struct mntarg * 2102 mount_arg(struct mntarg *ma, const char *name, const void *val, int len) 2103 { 2104 2105 if (ma == NULL) { 2106 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO); 2107 SLIST_INIT(&ma->list); 2108 } 2109 if (ma->error) 2110 return (ma); 2111 2112 ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2), 2113 M_MOUNT, M_WAITOK); 2114 ma->v[ma->len].iov_base = (void *)(uintptr_t)name; 2115 ma->v[ma->len].iov_len = strlen(name) + 1; 2116 ma->len++; 2117 2118 ma->v[ma->len].iov_base = (void *)(uintptr_t)val; 2119 if (len < 0) 2120 ma->v[ma->len].iov_len = strlen(val) + 1; 2121 else 2122 ma->v[ma->len].iov_len = len; 2123 ma->len++; 2124 return (ma); 2125 } 2126 2127 /* 2128 * Free a mntarg structure 2129 */ 2130 static void 2131 free_mntarg(struct mntarg *ma) 2132 { 2133 struct mntaarg *maa; 2134 2135 while (!SLIST_EMPTY(&ma->list)) { 2136 maa = SLIST_FIRST(&ma->list); 2137 SLIST_REMOVE_HEAD(&ma->list, next); 2138 free(maa, M_MOUNT); 2139 } 2140 free(ma->v, M_MOUNT); 2141 free(ma, M_MOUNT); 2142 } 2143 2144 /* 2145 * Mount a filesystem 2146 */ 2147 int 2148 kernel_mount(struct mntarg *ma, int flags) 2149 { 2150 struct uio auio; 2151 int error; 2152 2153 KASSERT(ma != NULL, ("kernel_mount NULL ma")); 2154 KASSERT(ma->v != NULL, ("kernel_mount NULL ma->v")); 2155 KASSERT(!(ma->len & 1), ("kernel_mount odd ma->len (%d)", ma->len)); 2156 2157 auio.uio_iov = ma->v; 2158 auio.uio_iovcnt = ma->len; 2159 auio.uio_segflg = UIO_SYSSPACE; 2160 2161 error = ma->error; 2162 if (!error) 2163 error = vfs_donmount(curthread, flags, &auio); 2164 free_mntarg(ma); 2165 return (error); 2166 } 2167 2168 /* 2169 * A printflike function to mount a filesystem. 2170 */ 2171 int 2172 kernel_vmount(int flags, ...) 2173 { 2174 struct mntarg *ma = NULL; 2175 va_list ap; 2176 const char *cp; 2177 const void *vp; 2178 int error; 2179 2180 va_start(ap, flags); 2181 for (;;) { 2182 cp = va_arg(ap, const char *); 2183 if (cp == NULL) 2184 break; 2185 vp = va_arg(ap, const void *); 2186 ma = mount_arg(ma, cp, vp, -1); 2187 } 2188 va_end(ap); 2189 2190 error = kernel_mount(ma, flags); 2191 return (error); 2192 } 2193