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 return (NULL); 1802 } 1803 1804 int 1805 vfs_flagopt(struct vfsoptlist *opts, const char *name, u_int *w, u_int val) 1806 { 1807 struct vfsopt *opt; 1808 1809 TAILQ_FOREACH(opt, opts, link) { 1810 if (strcmp(name, opt->name) == 0) { 1811 if (w != NULL) 1812 *w |= val; 1813 return (1); 1814 } 1815 } 1816 if (w != NULL) 1817 *w &= ~val; 1818 return (0); 1819 } 1820 1821 int 1822 vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...) 1823 { 1824 va_list ap; 1825 struct vfsopt *opt; 1826 int ret; 1827 1828 KASSERT(opts != NULL, ("vfs_getopt: caller passed 'opts' as NULL")); 1829 1830 TAILQ_FOREACH(opt, opts, link) { 1831 if (strcmp(name, opt->name) != 0) 1832 continue; 1833 if (((char *)opt->value)[opt->len - 1] != '\0') 1834 return (0); 1835 va_start(ap, fmt); 1836 ret = vsscanf(opt->value, fmt, ap); 1837 va_end(ap); 1838 return (ret); 1839 } 1840 return (0); 1841 } 1842 1843 /* 1844 * Find and copy a mount option. 1845 * 1846 * The size of the buffer has to be specified 1847 * in len, if it is not the same length as the 1848 * mount option, EINVAL is returned. 1849 * Returns ENOENT if the option is not found. 1850 */ 1851 int 1852 vfs_copyopt(opts, name, dest, len) 1853 struct vfsoptlist *opts; 1854 const char *name; 1855 void *dest; 1856 int len; 1857 { 1858 struct vfsopt *opt; 1859 1860 KASSERT(opts != NULL, ("vfs_copyopt: caller passed 'opts' as NULL")); 1861 1862 TAILQ_FOREACH(opt, opts, link) { 1863 if (strcmp(name, opt->name) == 0) { 1864 if (len != opt->len) 1865 return (EINVAL); 1866 bcopy(opt->value, dest, opt->len); 1867 return (0); 1868 } 1869 } 1870 return (ENOENT); 1871 } 1872 1873 /* 1874 * This is a helper function for filesystems to traverse their 1875 * vnodes. See MNT_VNODE_FOREACH() in sys/mount.h 1876 */ 1877 1878 struct vnode * 1879 __mnt_vnode_next(struct vnode **mvp, struct mount *mp) 1880 { 1881 struct vnode *vp; 1882 1883 mtx_assert(MNT_MTX(mp), MA_OWNED); 1884 1885 KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch")); 1886 vp = TAILQ_NEXT(*mvp, v_nmntvnodes); 1887 while (vp != NULL && vp->v_type == VMARKER) 1888 vp = TAILQ_NEXT(vp, v_nmntvnodes); 1889 1890 /* Check if we are done */ 1891 if (vp == NULL) { 1892 __mnt_vnode_markerfree(mvp, mp); 1893 return (NULL); 1894 } 1895 TAILQ_REMOVE(&mp->mnt_nvnodelist, *mvp, v_nmntvnodes); 1896 TAILQ_INSERT_AFTER(&mp->mnt_nvnodelist, vp, *mvp, v_nmntvnodes); 1897 return (vp); 1898 } 1899 1900 struct vnode * 1901 __mnt_vnode_first(struct vnode **mvp, struct mount *mp) 1902 { 1903 struct vnode *vp; 1904 1905 mtx_assert(MNT_MTX(mp), MA_OWNED); 1906 1907 vp = TAILQ_FIRST(&mp->mnt_nvnodelist); 1908 while (vp != NULL && vp->v_type == VMARKER) 1909 vp = TAILQ_NEXT(vp, v_nmntvnodes); 1910 1911 /* Check if we are done */ 1912 if (vp == NULL) { 1913 *mvp = NULL; 1914 return (NULL); 1915 } 1916 mp->mnt_holdcnt++; 1917 MNT_IUNLOCK(mp); 1918 *mvp = (struct vnode *) malloc(sizeof(struct vnode), 1919 M_VNODE_MARKER, 1920 M_WAITOK | M_ZERO); 1921 MNT_ILOCK(mp); 1922 (*mvp)->v_type = VMARKER; 1923 1924 vp = TAILQ_FIRST(&mp->mnt_nvnodelist); 1925 while (vp != NULL && vp->v_type == VMARKER) 1926 vp = TAILQ_NEXT(vp, v_nmntvnodes); 1927 1928 /* Check if we are done */ 1929 if (vp == NULL) { 1930 MNT_IUNLOCK(mp); 1931 free(*mvp, M_VNODE_MARKER); 1932 MNT_ILOCK(mp); 1933 *mvp = NULL; 1934 mp->mnt_holdcnt--; 1935 if (mp->mnt_holdcnt == 0 && mp->mnt_holdcntwaiters != 0) 1936 wakeup(&mp->mnt_holdcnt); 1937 return (NULL); 1938 } 1939 mp->mnt_markercnt++; 1940 (*mvp)->v_mount = mp; 1941 TAILQ_INSERT_AFTER(&mp->mnt_nvnodelist, vp, *mvp, v_nmntvnodes); 1942 return (vp); 1943 } 1944 1945 1946 void 1947 __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp) 1948 { 1949 1950 if (*mvp == NULL) 1951 return; 1952 1953 mtx_assert(MNT_MTX(mp), MA_OWNED); 1954 1955 KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch")); 1956 TAILQ_REMOVE(&mp->mnt_nvnodelist, *mvp, v_nmntvnodes); 1957 MNT_IUNLOCK(mp); 1958 free(*mvp, M_VNODE_MARKER); 1959 MNT_ILOCK(mp); 1960 *mvp = NULL; 1961 1962 mp->mnt_markercnt--; 1963 mp->mnt_holdcnt--; 1964 if (mp->mnt_holdcnt == 0 && mp->mnt_holdcntwaiters != 0) 1965 wakeup(&mp->mnt_holdcnt); 1966 } 1967 1968 1969 int 1970 __vfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) 1971 { 1972 int error; 1973 1974 error = mp->mnt_op->vfs_statfs(mp, &mp->mnt_stat, td); 1975 if (sbp != &mp->mnt_stat) 1976 *sbp = mp->mnt_stat; 1977 return (error); 1978 } 1979 1980 void 1981 vfs_mountedfrom(struct mount *mp, const char *from) 1982 { 1983 1984 bzero(mp->mnt_stat.f_mntfromname, sizeof mp->mnt_stat.f_mntfromname); 1985 strlcpy(mp->mnt_stat.f_mntfromname, from, 1986 sizeof mp->mnt_stat.f_mntfromname); 1987 } 1988 1989 /* 1990 * --------------------------------------------------------------------- 1991 * This is the api for building mount args and mounting filesystems from 1992 * inside the kernel. 1993 * 1994 * The API works by accumulation of individual args. First error is 1995 * latched. 1996 * 1997 * XXX: should be documented in new manpage kernel_mount(9) 1998 */ 1999 2000 /* A memory allocation which must be freed when we are done */ 2001 struct mntaarg { 2002 SLIST_ENTRY(mntaarg) next; 2003 }; 2004 2005 /* The header for the mount arguments */ 2006 struct mntarg { 2007 struct iovec *v; 2008 int len; 2009 int error; 2010 SLIST_HEAD(, mntaarg) list; 2011 }; 2012 2013 /* 2014 * Add a boolean argument. 2015 * 2016 * flag is the boolean value. 2017 * name must start with "no". 2018 */ 2019 struct mntarg * 2020 mount_argb(struct mntarg *ma, int flag, const char *name) 2021 { 2022 2023 KASSERT(name[0] == 'n' && name[1] == 'o', 2024 ("mount_argb(...,%s): name must start with 'no'", name)); 2025 2026 return (mount_arg(ma, name + (flag ? 2 : 0), NULL, 0)); 2027 } 2028 2029 /* 2030 * Add an argument printf style 2031 */ 2032 struct mntarg * 2033 mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...) 2034 { 2035 va_list ap; 2036 struct mntaarg *maa; 2037 struct sbuf *sb; 2038 int len; 2039 2040 if (ma == NULL) { 2041 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO); 2042 SLIST_INIT(&ma->list); 2043 } 2044 if (ma->error) 2045 return (ma); 2046 2047 ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2), 2048 M_MOUNT, M_WAITOK); 2049 ma->v[ma->len].iov_base = (void *)(uintptr_t)name; 2050 ma->v[ma->len].iov_len = strlen(name) + 1; 2051 ma->len++; 2052 2053 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 2054 va_start(ap, fmt); 2055 sbuf_vprintf(sb, fmt, ap); 2056 va_end(ap); 2057 sbuf_finish(sb); 2058 len = sbuf_len(sb) + 1; 2059 maa = malloc(sizeof *maa + len, M_MOUNT, M_WAITOK | M_ZERO); 2060 SLIST_INSERT_HEAD(&ma->list, maa, next); 2061 bcopy(sbuf_data(sb), maa + 1, len); 2062 sbuf_delete(sb); 2063 2064 ma->v[ma->len].iov_base = maa + 1; 2065 ma->v[ma->len].iov_len = len; 2066 ma->len++; 2067 2068 return (ma); 2069 } 2070 2071 /* 2072 * Add an argument which is a userland string. 2073 */ 2074 struct mntarg * 2075 mount_argsu(struct mntarg *ma, const char *name, const void *val, int len) 2076 { 2077 struct mntaarg *maa; 2078 char *tbuf; 2079 2080 if (val == NULL) 2081 return (ma); 2082 if (ma == NULL) { 2083 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO); 2084 SLIST_INIT(&ma->list); 2085 } 2086 if (ma->error) 2087 return (ma); 2088 maa = malloc(sizeof *maa + len, M_MOUNT, M_WAITOK | M_ZERO); 2089 SLIST_INSERT_HEAD(&ma->list, maa, next); 2090 tbuf = (void *)(maa + 1); 2091 ma->error = copyinstr(val, tbuf, len, NULL); 2092 return (mount_arg(ma, name, tbuf, -1)); 2093 } 2094 2095 /* 2096 * Plain argument. 2097 * 2098 * If length is -1, use printf. 2099 */ 2100 struct mntarg * 2101 mount_arg(struct mntarg *ma, const char *name, const void *val, int len) 2102 { 2103 2104 if (ma == NULL) { 2105 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO); 2106 SLIST_INIT(&ma->list); 2107 } 2108 if (ma->error) 2109 return (ma); 2110 2111 ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2), 2112 M_MOUNT, M_WAITOK); 2113 ma->v[ma->len].iov_base = (void *)(uintptr_t)name; 2114 ma->v[ma->len].iov_len = strlen(name) + 1; 2115 ma->len++; 2116 2117 ma->v[ma->len].iov_base = (void *)(uintptr_t)val; 2118 if (len < 0) 2119 ma->v[ma->len].iov_len = strlen(val) + 1; 2120 else 2121 ma->v[ma->len].iov_len = len; 2122 ma->len++; 2123 return (ma); 2124 } 2125 2126 /* 2127 * Free a mntarg structure 2128 */ 2129 static void 2130 free_mntarg(struct mntarg *ma) 2131 { 2132 struct mntaarg *maa; 2133 2134 while (!SLIST_EMPTY(&ma->list)) { 2135 maa = SLIST_FIRST(&ma->list); 2136 SLIST_REMOVE_HEAD(&ma->list, next); 2137 free(maa, M_MOUNT); 2138 } 2139 free(ma->v, M_MOUNT); 2140 free(ma, M_MOUNT); 2141 } 2142 2143 /* 2144 * Mount a filesystem 2145 */ 2146 int 2147 kernel_mount(struct mntarg *ma, int flags) 2148 { 2149 struct uio auio; 2150 int error; 2151 2152 KASSERT(ma != NULL, ("kernel_mount NULL ma")); 2153 KASSERT(ma->v != NULL, ("kernel_mount NULL ma->v")); 2154 KASSERT(!(ma->len & 1), ("kernel_mount odd ma->len (%d)", ma->len)); 2155 2156 auio.uio_iov = ma->v; 2157 auio.uio_iovcnt = ma->len; 2158 auio.uio_segflg = UIO_SYSSPACE; 2159 2160 error = ma->error; 2161 if (!error) 2162 error = vfs_donmount(curthread, flags, &auio); 2163 free_mntarg(ma); 2164 return (error); 2165 } 2166 2167 /* 2168 * A printflike function to mount a filesystem. 2169 */ 2170 int 2171 kernel_vmount(int flags, ...) 2172 { 2173 struct mntarg *ma = NULL; 2174 va_list ap; 2175 const char *cp; 2176 const void *vp; 2177 int error; 2178 2179 va_start(ap, flags); 2180 for (;;) { 2181 cp = va_arg(ap, const char *); 2182 if (cp == NULL) 2183 break; 2184 vp = va_arg(ap, const void *); 2185 ma = mount_arg(ma, cp, vp, -1); 2186 } 2187 va_end(ap); 2188 2189 error = kernel_mount(ma, flags); 2190 return (error); 2191 } 2192