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: stable/10/sys/kern/vfs_mount.c 332754 2018-04-19 05:52:47Z avg $"); 39 40#include <sys/param.h> 41#include <sys/conf.h> 42#include <sys/fcntl.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/sbuf.h> 55#include <sys/syscallsubr.h> 56#include <sys/sysproto.h> 57#include <sys/sx.h> 58#include <sys/sysctl.h> 59#include <sys/sysent.h> 60#include <sys/systm.h> 61#include <sys/vnode.h> 62#include <vm/uma.h> 63 64#include <geom/geom.h> 65 66#include <machine/stdarg.h> 67 68#include <security/audit/audit.h> 69#include <security/mac/mac_framework.h> 70 71#define VFS_MOUNTARG_SIZE_MAX (1024 * 64) 72 73static int vfs_domount(struct thread *td, const char *fstype, char *fspath, 74 uint64_t fsflags, struct vfsoptlist **optlist); 75static void free_mntarg(struct mntarg *ma); 76 77static int usermount = 0; 78SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, 79 "Unprivileged users may mount and unmount file systems"); 80 81static int default_autoro = false; 82SYSCTL_INT(_vfs, OID_AUTO, default_autoro, CTLFLAG_RW, &default_autoro, 0, 83 "Retry failed r/w mount as r/o if no explicit ro/rw option is specified"); 84 85MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure"); 86static uma_zone_t mount_zone; 87 88/* List of mounted filesystems. */ 89struct mntlist mountlist = TAILQ_HEAD_INITIALIZER(mountlist); 90 91/* For any iteration/modification of mountlist */ 92struct mtx mountlist_mtx; 93MTX_SYSINIT(mountlist, &mountlist_mtx, "mountlist", MTX_DEF); 94 95/* 96 * Global opts, taken by all filesystems 97 */ 98static const char *global_opts[] = { 99 "errmsg", 100 "fstype", 101 "fspath", 102 "ro", 103 "rw", 104 "nosuid", 105 "noexec", 106 NULL 107}; 108 109static int 110mount_init(void *mem, int size, int flags) 111{ 112 struct mount *mp; 113 114 mp = (struct mount *)mem; 115 mtx_init(&mp->mnt_mtx, "struct mount mtx", NULL, MTX_DEF); 116 lockinit(&mp->mnt_explock, PVFS, "explock", 0, 0); 117 return (0); 118} 119 120static void 121mount_fini(void *mem, int size) 122{ 123 struct mount *mp; 124 125 mp = (struct mount *)mem; 126 lockdestroy(&mp->mnt_explock); 127 mtx_destroy(&mp->mnt_mtx); 128} 129 130static void 131vfs_mount_init(void *dummy __unused) 132{ 133 134 mount_zone = uma_zcreate("Mountpoints", sizeof(struct mount), NULL, 135 NULL, mount_init, mount_fini, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); 136} 137SYSINIT(vfs_mount, SI_SUB_VFS, SI_ORDER_ANY, vfs_mount_init, NULL); 138 139/* 140 * --------------------------------------------------------------------- 141 * Functions for building and sanitizing the mount options 142 */ 143 144/* Remove one mount option. */ 145static void 146vfs_freeopt(struct vfsoptlist *opts, struct vfsopt *opt) 147{ 148 149 TAILQ_REMOVE(opts, opt, link); 150 free(opt->name, M_MOUNT); 151 if (opt->value != NULL) 152 free(opt->value, M_MOUNT); 153 free(opt, M_MOUNT); 154} 155 156/* Release all resources related to the mount options. */ 157void 158vfs_freeopts(struct vfsoptlist *opts) 159{ 160 struct vfsopt *opt; 161 162 while (!TAILQ_EMPTY(opts)) { 163 opt = TAILQ_FIRST(opts); 164 vfs_freeopt(opts, opt); 165 } 166 free(opts, M_MOUNT); 167} 168 169void 170vfs_deleteopt(struct vfsoptlist *opts, const char *name) 171{ 172 struct vfsopt *opt, *temp; 173 174 if (opts == NULL) 175 return; 176 TAILQ_FOREACH_SAFE(opt, opts, link, temp) { 177 if (strcmp(opt->name, name) == 0) 178 vfs_freeopt(opts, opt); 179 } 180} 181 182static int 183vfs_isopt_ro(const char *opt) 184{ 185 186 if (strcmp(opt, "ro") == 0 || strcmp(opt, "rdonly") == 0 || 187 strcmp(opt, "norw") == 0) 188 return (1); 189 return (0); 190} 191 192static int 193vfs_isopt_rw(const char *opt) 194{ 195 196 if (strcmp(opt, "rw") == 0 || strcmp(opt, "noro") == 0) 197 return (1); 198 return (0); 199} 200 201/* 202 * Check if options are equal (with or without the "no" prefix). 203 */ 204static int 205vfs_equalopts(const char *opt1, const char *opt2) 206{ 207 char *p; 208 209 /* "opt" vs. "opt" or "noopt" vs. "noopt" */ 210 if (strcmp(opt1, opt2) == 0) 211 return (1); 212 /* "noopt" vs. "opt" */ 213 if (strncmp(opt1, "no", 2) == 0 && strcmp(opt1 + 2, opt2) == 0) 214 return (1); 215 /* "opt" vs. "noopt" */ 216 if (strncmp(opt2, "no", 2) == 0 && strcmp(opt1, opt2 + 2) == 0) 217 return (1); 218 while ((p = strchr(opt1, '.')) != NULL && 219 !strncmp(opt1, opt2, ++p - opt1)) { 220 opt2 += p - opt1; 221 opt1 = p; 222 /* "foo.noopt" vs. "foo.opt" */ 223 if (strncmp(opt1, "no", 2) == 0 && strcmp(opt1 + 2, opt2) == 0) 224 return (1); 225 /* "foo.opt" vs. "foo.noopt" */ 226 if (strncmp(opt2, "no", 2) == 0 && strcmp(opt1, opt2 + 2) == 0) 227 return (1); 228 } 229 /* "ro" / "rdonly" / "norw" / "rw" / "noro" */ 230 if ((vfs_isopt_ro(opt1) || vfs_isopt_rw(opt1)) && 231 (vfs_isopt_ro(opt2) || vfs_isopt_rw(opt2))) 232 return (1); 233 return (0); 234} 235 236/* 237 * If a mount option is specified several times, 238 * (with or without the "no" prefix) only keep 239 * the last occurrence of it. 240 */ 241static void 242vfs_sanitizeopts(struct vfsoptlist *opts) 243{ 244 struct vfsopt *opt, *opt2, *tmp; 245 246 TAILQ_FOREACH_REVERSE(opt, opts, vfsoptlist, link) { 247 opt2 = TAILQ_PREV(opt, vfsoptlist, link); 248 while (opt2 != NULL) { 249 if (vfs_equalopts(opt->name, opt2->name)) { 250 tmp = TAILQ_PREV(opt2, vfsoptlist, link); 251 vfs_freeopt(opts, opt2); 252 opt2 = tmp; 253 } else { 254 opt2 = TAILQ_PREV(opt2, vfsoptlist, link); 255 } 256 } 257 } 258} 259 260/* 261 * Build a linked list of mount options from a struct uio. 262 */ 263int 264vfs_buildopts(struct uio *auio, struct vfsoptlist **options) 265{ 266 struct vfsoptlist *opts; 267 struct vfsopt *opt; 268 size_t memused, namelen, optlen; 269 unsigned int i, iovcnt; 270 int error; 271 272 opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); 273 TAILQ_INIT(opts); 274 memused = 0; 275 iovcnt = auio->uio_iovcnt; 276 for (i = 0; i < iovcnt; i += 2) { 277 namelen = auio->uio_iov[i].iov_len; 278 optlen = auio->uio_iov[i + 1].iov_len; 279 memused += sizeof(struct vfsopt) + optlen + namelen; 280 /* 281 * Avoid consuming too much memory, and attempts to overflow 282 * memused. 283 */ 284 if (memused > VFS_MOUNTARG_SIZE_MAX || 285 optlen > VFS_MOUNTARG_SIZE_MAX || 286 namelen > VFS_MOUNTARG_SIZE_MAX) { 287 error = EINVAL; 288 goto bad; 289 } 290 291 opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK); 292 opt->name = malloc(namelen, M_MOUNT, M_WAITOK); 293 opt->value = NULL; 294 opt->len = 0; 295 opt->pos = i / 2; 296 opt->seen = 0; 297 298 /* 299 * Do this early, so jumps to "bad" will free the current 300 * option. 301 */ 302 TAILQ_INSERT_TAIL(opts, opt, link); 303 304 if (auio->uio_segflg == UIO_SYSSPACE) { 305 bcopy(auio->uio_iov[i].iov_base, opt->name, namelen); 306 } else { 307 error = copyin(auio->uio_iov[i].iov_base, opt->name, 308 namelen); 309 if (error) 310 goto bad; 311 } 312 /* Ensure names are null-terminated strings. */ 313 if (namelen == 0 || opt->name[namelen - 1] != '\0') { 314 error = EINVAL; 315 goto bad; 316 } 317 if (optlen != 0) { 318 opt->len = optlen; 319 opt->value = malloc(optlen, M_MOUNT, M_WAITOK); 320 if (auio->uio_segflg == UIO_SYSSPACE) { 321 bcopy(auio->uio_iov[i + 1].iov_base, opt->value, 322 optlen); 323 } else { 324 error = copyin(auio->uio_iov[i + 1].iov_base, 325 opt->value, optlen); 326 if (error) 327 goto bad; 328 } 329 } 330 } 331 vfs_sanitizeopts(opts); 332 *options = opts; 333 return (0); 334bad: 335 vfs_freeopts(opts); 336 return (error); 337} 338 339/* 340 * Merge the old mount options with the new ones passed 341 * in the MNT_UPDATE case. 342 * 343 * XXX: This function will keep a "nofoo" option in the new 344 * options. E.g, if the option's canonical name is "foo", 345 * "nofoo" ends up in the mount point's active options. 346 */ 347static void 348vfs_mergeopts(struct vfsoptlist *toopts, struct vfsoptlist *oldopts) 349{ 350 struct vfsopt *opt, *new; 351 352 TAILQ_FOREACH(opt, oldopts, link) { 353 new = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK); 354 new->name = strdup(opt->name, M_MOUNT); 355 if (opt->len != 0) { 356 new->value = malloc(opt->len, M_MOUNT, M_WAITOK); 357 bcopy(opt->value, new->value, opt->len); 358 } else 359 new->value = NULL; 360 new->len = opt->len; 361 new->seen = opt->seen; 362 TAILQ_INSERT_HEAD(toopts, new, link); 363 } 364 vfs_sanitizeopts(toopts); 365} 366 367/* 368 * Mount a filesystem. 369 */ 370int 371sys_nmount(td, uap) 372 struct thread *td; 373 struct nmount_args /* { 374 struct iovec *iovp; 375 unsigned int iovcnt; 376 int flags; 377 } */ *uap; 378{ 379 struct uio *auio; 380 int error; 381 u_int iovcnt; 382 uint64_t flags; 383 384 /* 385 * Mount flags are now 64-bits. On 32-bit archtectures only 386 * 32-bits are passed in, but from here on everything handles 387 * 64-bit flags correctly. 388 */ 389 flags = uap->flags; 390 391 AUDIT_ARG_FFLAGS(flags); 392 CTR4(KTR_VFS, "%s: iovp %p with iovcnt %d and flags %d", __func__, 393 uap->iovp, uap->iovcnt, flags); 394 395 /* 396 * Filter out MNT_ROOTFS. We do not want clients of nmount() in 397 * userspace to set this flag, but we must filter it out if we want 398 * MNT_UPDATE on the root file system to work. 399 * MNT_ROOTFS should only be set by the kernel when mounting its 400 * root file system. 401 */ 402 flags &= ~MNT_ROOTFS; 403 404 iovcnt = uap->iovcnt; 405 /* 406 * Check that we have an even number of iovec's 407 * and that we have at least two options. 408 */ 409 if ((iovcnt & 1) || (iovcnt < 4)) { 410 CTR2(KTR_VFS, "%s: failed for invalid iovcnt %d", __func__, 411 uap->iovcnt); 412 return (EINVAL); 413 } 414 415 error = copyinuio(uap->iovp, iovcnt, &auio); 416 if (error) { 417 CTR2(KTR_VFS, "%s: failed for invalid uio op with %d errno", 418 __func__, error); 419 return (error); 420 } 421 error = vfs_donmount(td, flags, auio); 422 423 free(auio, M_IOV); 424 return (error); 425} 426 427/* 428 * --------------------------------------------------------------------- 429 * Various utility functions 430 */ 431 432void 433vfs_ref(struct mount *mp) 434{ 435 436 CTR2(KTR_VFS, "%s: mp %p", __func__, mp); 437 MNT_ILOCK(mp); 438 MNT_REF(mp); 439 MNT_IUNLOCK(mp); 440} 441 442void 443vfs_rel(struct mount *mp) 444{ 445 446 CTR2(KTR_VFS, "%s: mp %p", __func__, mp); 447 MNT_ILOCK(mp); 448 MNT_REL(mp); 449 MNT_IUNLOCK(mp); 450} 451 452/* 453 * Allocate and initialize the mount point struct. 454 */ 455struct mount * 456vfs_mount_alloc(struct vnode *vp, struct vfsconf *vfsp, const char *fspath, 457 struct ucred *cred) 458{ 459 struct mount *mp; 460 461 mp = uma_zalloc(mount_zone, M_WAITOK); 462 bzero(&mp->mnt_startzero, 463 __rangeof(struct mount, mnt_startzero, mnt_endzero)); 464 TAILQ_INIT(&mp->mnt_nvnodelist); 465 mp->mnt_nvnodelistsize = 0; 466 TAILQ_INIT(&mp->mnt_activevnodelist); 467 mp->mnt_activevnodelistsize = 0; 468 mp->mnt_ref = 0; 469 (void) vfs_busy(mp, MBF_NOWAIT); 470 atomic_add_acq_int(&vfsp->vfc_refcount, 1); 471 mp->mnt_op = vfsp->vfc_vfsops; 472 mp->mnt_vfc = vfsp; 473 mp->mnt_stat.f_type = vfsp->vfc_typenum; 474 mp->mnt_gen++; 475 strlcpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN); 476 mp->mnt_vnodecovered = vp; 477 mp->mnt_cred = crdup(cred); 478 mp->mnt_stat.f_owner = cred->cr_uid; 479 strlcpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN); 480 mp->mnt_iosize_max = DFLTPHYS; 481#ifdef MAC 482 mac_mount_init(mp); 483 mac_mount_create(cred, mp); 484#endif 485 arc4rand(&mp->mnt_hashseed, sizeof mp->mnt_hashseed, 0); 486 TAILQ_INIT(&mp->mnt_uppers); 487 return (mp); 488} 489 490/* 491 * Destroy the mount struct previously allocated by vfs_mount_alloc(). 492 */ 493void 494vfs_mount_destroy(struct mount *mp) 495{ 496 497 MNT_ILOCK(mp); 498 mp->mnt_kern_flag |= MNTK_REFEXPIRE; 499 if (mp->mnt_kern_flag & MNTK_MWAIT) { 500 mp->mnt_kern_flag &= ~MNTK_MWAIT; 501 wakeup(mp); 502 } 503 while (mp->mnt_ref) 504 msleep(mp, MNT_MTX(mp), PVFS, "mntref", 0); 505 KASSERT(mp->mnt_ref == 0, 506 ("%s: invalid refcount in the drain path @ %s:%d", __func__, 507 __FILE__, __LINE__)); 508 if (mp->mnt_writeopcount != 0) 509 panic("vfs_mount_destroy: nonzero writeopcount"); 510 if (mp->mnt_secondary_writes != 0) 511 panic("vfs_mount_destroy: nonzero secondary_writes"); 512 atomic_subtract_rel_int(&mp->mnt_vfc->vfc_refcount, 1); 513 if (!TAILQ_EMPTY(&mp->mnt_nvnodelist)) { 514 struct vnode *vp; 515 516 TAILQ_FOREACH(vp, &mp->mnt_nvnodelist, v_nmntvnodes) 517 vprint("", vp); 518 panic("unmount: dangling vnode"); 519 } 520 KASSERT(TAILQ_EMPTY(&mp->mnt_uppers), ("mnt_uppers")); 521 if (mp->mnt_nvnodelistsize != 0) 522 panic("vfs_mount_destroy: nonzero nvnodelistsize"); 523 if (mp->mnt_activevnodelistsize != 0) 524 panic("vfs_mount_destroy: nonzero activevnodelistsize"); 525 if (mp->mnt_lockref != 0) 526 panic("vfs_mount_destroy: nonzero lock refcount"); 527 MNT_IUNLOCK(mp); 528 if (mp->mnt_vnodecovered != NULL) 529 vrele(mp->mnt_vnodecovered); 530#ifdef MAC 531 mac_mount_destroy(mp); 532#endif 533 if (mp->mnt_opt != NULL) 534 vfs_freeopts(mp->mnt_opt); 535 crfree(mp->mnt_cred); 536 uma_zfree(mount_zone, mp); 537} 538 539static bool 540vfs_should_downgrade_to_ro_mount(uint64_t fsflags, int error) 541{ 542 /* This is an upgrade of an exisiting mount. */ 543 if ((fsflags & MNT_UPDATE) != 0) 544 return (false); 545 /* This is already an R/O mount. */ 546 if ((fsflags & MNT_RDONLY) != 0) 547 return (false); 548 549 switch (error) { 550 case ENODEV: /* generic, geom, ... */ 551 case EACCES: /* cam/scsi, ... */ 552 case EROFS: /* md, mmcsd, ... */ 553 /* 554 * These errors can be returned by the storage layer to signal 555 * that the media is read-only. No harm in the R/O mount 556 * attempt if the error was returned for some other reason. 557 */ 558 return (true); 559 default: 560 return (false); 561 } 562} 563 564int 565vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions) 566{ 567 struct vfsoptlist *optlist; 568 struct vfsopt *opt, *tmp_opt; 569 char *fstype, *fspath, *errmsg; 570 int error, fstypelen, fspathlen, errmsg_len, errmsg_pos; 571 bool autoro; 572 573 errmsg = fspath = NULL; 574 errmsg_len = fspathlen = 0; 575 errmsg_pos = -1; 576 autoro = default_autoro; 577 578 error = vfs_buildopts(fsoptions, &optlist); 579 if (error) 580 return (error); 581 582 if (vfs_getopt(optlist, "errmsg", (void **)&errmsg, &errmsg_len) == 0) 583 errmsg_pos = vfs_getopt_pos(optlist, "errmsg"); 584 585 /* 586 * We need these two options before the others, 587 * and they are mandatory for any filesystem. 588 * Ensure they are NUL terminated as well. 589 */ 590 fstypelen = 0; 591 error = vfs_getopt(optlist, "fstype", (void **)&fstype, &fstypelen); 592 if (error || fstype[fstypelen - 1] != '\0') { 593 error = EINVAL; 594 if (errmsg != NULL) 595 strncpy(errmsg, "Invalid fstype", errmsg_len); 596 goto bail; 597 } 598 fspathlen = 0; 599 error = vfs_getopt(optlist, "fspath", (void **)&fspath, &fspathlen); 600 if (error || fspath[fspathlen - 1] != '\0') { 601 error = EINVAL; 602 if (errmsg != NULL) 603 strncpy(errmsg, "Invalid fspath", errmsg_len); 604 goto bail; 605 } 606 607 /* 608 * We need to see if we have the "update" option 609 * before we call vfs_domount(), since vfs_domount() has special 610 * logic based on MNT_UPDATE. This is very important 611 * when we want to update the root filesystem. 612 */ 613 TAILQ_FOREACH_SAFE(opt, optlist, link, tmp_opt) { 614 if (strcmp(opt->name, "update") == 0) { 615 fsflags |= MNT_UPDATE; 616 vfs_freeopt(optlist, opt); 617 } 618 else if (strcmp(opt->name, "async") == 0) 619 fsflags |= MNT_ASYNC; 620 else if (strcmp(opt->name, "force") == 0) { 621 fsflags |= MNT_FORCE; 622 vfs_freeopt(optlist, opt); 623 } 624 else if (strcmp(opt->name, "reload") == 0) { 625 fsflags |= MNT_RELOAD; 626 vfs_freeopt(optlist, opt); 627 } 628 else if (strcmp(opt->name, "multilabel") == 0) 629 fsflags |= MNT_MULTILABEL; 630 else if (strcmp(opt->name, "noasync") == 0) 631 fsflags &= ~MNT_ASYNC; 632 else if (strcmp(opt->name, "noatime") == 0) 633 fsflags |= MNT_NOATIME; 634 else if (strcmp(opt->name, "atime") == 0) { 635 free(opt->name, M_MOUNT); 636 opt->name = strdup("nonoatime", M_MOUNT); 637 } 638 else if (strcmp(opt->name, "noclusterr") == 0) 639 fsflags |= MNT_NOCLUSTERR; 640 else if (strcmp(opt->name, "clusterr") == 0) { 641 free(opt->name, M_MOUNT); 642 opt->name = strdup("nonoclusterr", M_MOUNT); 643 } 644 else if (strcmp(opt->name, "noclusterw") == 0) 645 fsflags |= MNT_NOCLUSTERW; 646 else if (strcmp(opt->name, "clusterw") == 0) { 647 free(opt->name, M_MOUNT); 648 opt->name = strdup("nonoclusterw", M_MOUNT); 649 } 650 else if (strcmp(opt->name, "noexec") == 0) 651 fsflags |= MNT_NOEXEC; 652 else if (strcmp(opt->name, "exec") == 0) { 653 free(opt->name, M_MOUNT); 654 opt->name = strdup("nonoexec", M_MOUNT); 655 } 656 else if (strcmp(opt->name, "nosuid") == 0) 657 fsflags |= MNT_NOSUID; 658 else if (strcmp(opt->name, "suid") == 0) { 659 free(opt->name, M_MOUNT); 660 opt->name = strdup("nonosuid", M_MOUNT); 661 } 662 else if (strcmp(opt->name, "nosymfollow") == 0) 663 fsflags |= MNT_NOSYMFOLLOW; 664 else if (strcmp(opt->name, "symfollow") == 0) { 665 free(opt->name, M_MOUNT); 666 opt->name = strdup("nonosymfollow", M_MOUNT); 667 } 668 else if (strcmp(opt->name, "noro") == 0) { 669 fsflags &= ~MNT_RDONLY; 670 autoro = false; 671 } 672 else if (strcmp(opt->name, "rw") == 0) { 673 fsflags &= ~MNT_RDONLY; 674 autoro = false; 675 } 676 else if (strcmp(opt->name, "ro") == 0) { 677 fsflags |= MNT_RDONLY; 678 autoro = false; 679 } 680 else if (strcmp(opt->name, "rdonly") == 0) { 681 free(opt->name, M_MOUNT); 682 opt->name = strdup("ro", M_MOUNT); 683 fsflags |= MNT_RDONLY; 684 autoro = false; 685 } 686 else if (strcmp(opt->name, "autoro") == 0) { 687 vfs_freeopt(optlist, opt); 688 autoro = true; 689 } 690 else if (strcmp(opt->name, "suiddir") == 0) 691 fsflags |= MNT_SUIDDIR; 692 else if (strcmp(opt->name, "sync") == 0) 693 fsflags |= MNT_SYNCHRONOUS; 694 else if (strcmp(opt->name, "union") == 0) 695 fsflags |= MNT_UNION; 696 else if (strcmp(opt->name, "automounted") == 0) { 697 fsflags |= MNT_AUTOMOUNTED; 698 vfs_freeopt(optlist, opt); 699 } 700 } 701 702 /* 703 * Be ultra-paranoid about making sure the type and fspath 704 * variables will fit in our mp buffers, including the 705 * terminating NUL. 706 */ 707 if (fstypelen > MFSNAMELEN || fspathlen > MNAMELEN) { 708 error = ENAMETOOLONG; 709 goto bail; 710 } 711 712 error = vfs_domount(td, fstype, fspath, fsflags, &optlist); 713 714 /* 715 * See if we can mount in the read-only mode if the error code suggests 716 * that it could be possible and the mount options allow for that. 717 * Never try it if "[no]{ro|rw}" has been explicitly requested and not 718 * overridden by "autoro". 719 */ 720 if (autoro && vfs_should_downgrade_to_ro_mount(fsflags, error)) { 721 printf("%s: R/W mount failed, possibly R/O media," 722 " trying R/O mount\n", __func__); 723 fsflags |= MNT_RDONLY; 724 error = vfs_domount(td, fstype, fspath, fsflags, &optlist); 725 } 726bail: 727 /* copyout the errmsg */ 728 if (errmsg_pos != -1 && ((2 * errmsg_pos + 1) < fsoptions->uio_iovcnt) 729 && errmsg_len > 0 && errmsg != NULL) { 730 if (fsoptions->uio_segflg == UIO_SYSSPACE) { 731 bcopy(errmsg, 732 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_base, 733 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_len); 734 } else { 735 copyout(errmsg, 736 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_base, 737 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_len); 738 } 739 } 740 741 if (optlist != NULL) 742 vfs_freeopts(optlist); 743 return (error); 744} 745 746/* 747 * Old mount API. 748 */ 749#ifndef _SYS_SYSPROTO_H_ 750struct mount_args { 751 char *type; 752 char *path; 753 int flags; 754 caddr_t data; 755}; 756#endif 757/* ARGSUSED */ 758int 759sys_mount(td, uap) 760 struct thread *td; 761 struct mount_args /* { 762 char *type; 763 char *path; 764 int flags; 765 caddr_t data; 766 } */ *uap; 767{ 768 char *fstype; 769 struct vfsconf *vfsp = NULL; 770 struct mntarg *ma = NULL; 771 uint64_t flags; 772 int error; 773 774 /* 775 * Mount flags are now 64-bits. On 32-bit architectures only 776 * 32-bits are passed in, but from here on everything handles 777 * 64-bit flags correctly. 778 */ 779 flags = uap->flags; 780 781 AUDIT_ARG_FFLAGS(flags); 782 783 /* 784 * Filter out MNT_ROOTFS. We do not want clients of mount() in 785 * userspace to set this flag, but we must filter it out if we want 786 * MNT_UPDATE on the root file system to work. 787 * MNT_ROOTFS should only be set by the kernel when mounting its 788 * root file system. 789 */ 790 flags &= ~MNT_ROOTFS; 791 792 fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK); 793 error = copyinstr(uap->type, fstype, MFSNAMELEN, NULL); 794 if (error) { 795 free(fstype, M_TEMP); 796 return (error); 797 } 798 799 AUDIT_ARG_TEXT(fstype); 800 vfsp = vfs_byname_kld(fstype, td, &error); 801 free(fstype, M_TEMP); 802 if (vfsp == NULL) 803 return (ENOENT); 804 if (vfsp->vfc_vfsops->vfs_cmount == NULL) 805 return (EOPNOTSUPP); 806 807 ma = mount_argsu(ma, "fstype", uap->type, MFSNAMELEN); 808 ma = mount_argsu(ma, "fspath", uap->path, MNAMELEN); 809 ma = mount_argb(ma, flags & MNT_RDONLY, "noro"); 810 ma = mount_argb(ma, !(flags & MNT_NOSUID), "nosuid"); 811 ma = mount_argb(ma, !(flags & MNT_NOEXEC), "noexec"); 812 813 error = vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, flags); 814 return (error); 815} 816 817/* 818 * vfs_domount_first(): first file system mount (not update) 819 */ 820static int 821vfs_domount_first( 822 struct thread *td, /* Calling thread. */ 823 struct vfsconf *vfsp, /* File system type. */ 824 char *fspath, /* Mount path. */ 825 struct vnode *vp, /* Vnode to be covered. */ 826 uint64_t fsflags, /* Flags common to all filesystems. */ 827 struct vfsoptlist **optlist /* Options local to the filesystem. */ 828 ) 829{ 830 struct vattr va; 831 struct mount *mp; 832 struct vnode *newdp; 833 int error; 834 835 ASSERT_VOP_ELOCKED(vp, __func__); 836 KASSERT((fsflags & MNT_UPDATE) == 0, ("MNT_UPDATE shouldn't be here")); 837 838 /* 839 * If the user is not root, ensure that they own the directory 840 * onto which we are attempting to mount. 841 */ 842 error = VOP_GETATTR(vp, &va, td->td_ucred); 843 if (error == 0 && va.va_uid != td->td_ucred->cr_uid) 844 error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN, 0); 845 if (error == 0) 846 error = vinvalbuf(vp, V_SAVE, 0, 0); 847 if (error == 0 && vp->v_type != VDIR) 848 error = ENOTDIR; 849 if (error == 0) { 850 VI_LOCK(vp); 851 if ((vp->v_iflag & VI_MOUNT) == 0 && vp->v_mountedhere == NULL) 852 vp->v_iflag |= VI_MOUNT; 853 else 854 error = EBUSY; 855 VI_UNLOCK(vp); 856 } 857 if (error != 0) { 858 vput(vp); 859 return (error); 860 } 861 VOP_UNLOCK(vp, 0); 862 863 /* Allocate and initialize the filesystem. */ 864 mp = vfs_mount_alloc(vp, vfsp, fspath, td->td_ucred); 865 /* XXXMAC: pass to vfs_mount_alloc? */ 866 mp->mnt_optnew = *optlist; 867 /* Set the mount level flags. */ 868 mp->mnt_flag = (fsflags & (MNT_UPDATEMASK | MNT_ROOTFS | MNT_RDONLY)); 869 870 /* 871 * Mount the filesystem. 872 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they 873 * get. No freeing of cn_pnbuf. 874 */ 875 error = VFS_MOUNT(mp); 876 if (error != 0) { 877 vfs_unbusy(mp); 878 mp->mnt_vnodecovered = NULL; 879 vfs_mount_destroy(mp); 880 VI_LOCK(vp); 881 vp->v_iflag &= ~VI_MOUNT; 882 VI_UNLOCK(vp); 883 vrele(vp); 884 return (error); 885 } 886 887 if (mp->mnt_opt != NULL) 888 vfs_freeopts(mp->mnt_opt); 889 mp->mnt_opt = mp->mnt_optnew; 890 *optlist = NULL; 891 (void)VFS_STATFS(mp, &mp->mnt_stat); 892 893 /* 894 * Prevent external consumers of mount options from reading mnt_optnew. 895 */ 896 mp->mnt_optnew = NULL; 897 898 MNT_ILOCK(mp); 899 if ((mp->mnt_flag & MNT_ASYNC) != 0 && 900 (mp->mnt_kern_flag & MNTK_NOASYNC) == 0) 901 mp->mnt_kern_flag |= MNTK_ASYNC; 902 else 903 mp->mnt_kern_flag &= ~MNTK_ASYNC; 904 MNT_IUNLOCK(mp); 905 906 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 907 cache_purge(vp); 908 VI_LOCK(vp); 909 vp->v_iflag &= ~VI_MOUNT; 910 VI_UNLOCK(vp); 911 vp->v_mountedhere = mp; 912 /* Place the new filesystem at the end of the mount list. */ 913 mtx_lock(&mountlist_mtx); 914 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); 915 mtx_unlock(&mountlist_mtx); 916 vfs_event_signal(NULL, VQ_MOUNT, 0); 917 if (VFS_ROOT(mp, LK_EXCLUSIVE, &newdp)) 918 panic("mount: lost mount"); 919 VOP_UNLOCK(vp, 0); 920 EVENTHANDLER_INVOKE(vfs_mounted, mp, newdp, td); 921 VOP_UNLOCK(newdp, 0); 922 mountcheckdirs(vp, newdp); 923 vrele(newdp); 924 if ((mp->mnt_flag & MNT_RDONLY) == 0) 925 vfs_allocate_syncvnode(mp); 926 vfs_unbusy(mp); 927 return (0); 928} 929 930/* 931 * vfs_domount_update(): update of mounted file system 932 */ 933static int 934vfs_domount_update( 935 struct thread *td, /* Calling thread. */ 936 struct vnode *vp, /* Mount point vnode. */ 937 uint64_t fsflags, /* Flags common to all filesystems. */ 938 struct vfsoptlist **optlist /* Options local to the filesystem. */ 939 ) 940{ 941 struct oexport_args oexport; 942 struct export_args export; 943 struct mount *mp; 944 int error, export_error; 945 uint64_t flag; 946 947 ASSERT_VOP_ELOCKED(vp, __func__); 948 KASSERT((fsflags & MNT_UPDATE) != 0, ("MNT_UPDATE should be here")); 949 mp = vp->v_mount; 950 951 if ((vp->v_vflag & VV_ROOT) == 0) { 952 if (vfs_copyopt(*optlist, "export", &export, sizeof(export)) 953 == 0) 954 error = EXDEV; 955 else 956 error = EINVAL; 957 vput(vp); 958 return (error); 959 } 960 961 /* 962 * We only allow the filesystem to be reloaded if it 963 * is currently mounted read-only. 964 */ 965 flag = mp->mnt_flag; 966 if ((fsflags & MNT_RELOAD) != 0 && (flag & MNT_RDONLY) == 0) { 967 vput(vp); 968 return (EOPNOTSUPP); /* Needs translation */ 969 } 970 /* 971 * Only privileged root, or (if MNT_USER is set) the user that 972 * did the original mount is permitted to update it. 973 */ 974 error = vfs_suser(mp, td); 975 if (error != 0) { 976 vput(vp); 977 return (error); 978 } 979 if (vfs_busy(mp, MBF_NOWAIT)) { 980 vput(vp); 981 return (EBUSY); 982 } 983 VI_LOCK(vp); 984 if ((vp->v_iflag & VI_MOUNT) != 0 || vp->v_mountedhere != NULL) { 985 VI_UNLOCK(vp); 986 vfs_unbusy(mp); 987 vput(vp); 988 return (EBUSY); 989 } 990 vp->v_iflag |= VI_MOUNT; 991 VI_UNLOCK(vp); 992 VOP_UNLOCK(vp, 0); 993 994 MNT_ILOCK(mp); 995 if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0) { 996 MNT_IUNLOCK(mp); 997 error = EBUSY; 998 goto end; 999 } 1000 mp->mnt_flag &= ~MNT_UPDATEMASK; 1001 mp->mnt_flag |= fsflags & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | 1002 MNT_SNAPSHOT | MNT_ROOTFS | MNT_UPDATEMASK | MNT_RDONLY); 1003 if ((mp->mnt_flag & MNT_ASYNC) == 0) 1004 mp->mnt_kern_flag &= ~MNTK_ASYNC; 1005 MNT_IUNLOCK(mp); 1006 mp->mnt_optnew = *optlist; 1007 vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt); 1008 1009 /* 1010 * Mount the filesystem. 1011 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they 1012 * get. No freeing of cn_pnbuf. 1013 */ 1014 error = VFS_MOUNT(mp); 1015 1016 export_error = 0; 1017 if (error == 0) { 1018 /* Process the export option. */ 1019 if (vfs_copyopt(mp->mnt_optnew, "export", &export, 1020 sizeof(export)) == 0) { 1021 export_error = vfs_export(mp, &export); 1022 } else if (vfs_copyopt(mp->mnt_optnew, "export", &oexport, 1023 sizeof(oexport)) == 0) { 1024 export.ex_flags = oexport.ex_flags; 1025 export.ex_root = oexport.ex_root; 1026 export.ex_anon = oexport.ex_anon; 1027 export.ex_addr = oexport.ex_addr; 1028 export.ex_addrlen = oexport.ex_addrlen; 1029 export.ex_mask = oexport.ex_mask; 1030 export.ex_masklen = oexport.ex_masklen; 1031 export.ex_indexfile = oexport.ex_indexfile; 1032 export.ex_numsecflavors = 0; 1033 export_error = vfs_export(mp, &export); 1034 } 1035 } 1036 1037 MNT_ILOCK(mp); 1038 if (error == 0) { 1039 mp->mnt_flag &= ~(MNT_UPDATE | MNT_RELOAD | MNT_FORCE | 1040 MNT_SNAPSHOT); 1041 } else { 1042 /* 1043 * If we fail, restore old mount flags. MNT_QUOTA is special, 1044 * because it is not part of MNT_UPDATEMASK, but it could have 1045 * changed in the meantime if quotactl(2) was called. 1046 * All in all we want current value of MNT_QUOTA, not the old 1047 * one. 1048 */ 1049 mp->mnt_flag = (mp->mnt_flag & MNT_QUOTA) | (flag & ~MNT_QUOTA); 1050 } 1051 if ((mp->mnt_flag & MNT_ASYNC) != 0 && 1052 (mp->mnt_kern_flag & MNTK_NOASYNC) == 0) 1053 mp->mnt_kern_flag |= MNTK_ASYNC; 1054 else 1055 mp->mnt_kern_flag &= ~MNTK_ASYNC; 1056 MNT_IUNLOCK(mp); 1057 1058 if (error != 0) 1059 goto end; 1060 1061 if (mp->mnt_opt != NULL) 1062 vfs_freeopts(mp->mnt_opt); 1063 mp->mnt_opt = mp->mnt_optnew; 1064 *optlist = NULL; 1065 (void)VFS_STATFS(mp, &mp->mnt_stat); 1066 /* 1067 * Prevent external consumers of mount options from reading 1068 * mnt_optnew. 1069 */ 1070 mp->mnt_optnew = NULL; 1071 1072 if ((mp->mnt_flag & MNT_RDONLY) == 0) 1073 vfs_allocate_syncvnode(mp); 1074 else 1075 vfs_deallocate_syncvnode(mp); 1076end: 1077 vfs_unbusy(mp); 1078 VI_LOCK(vp); 1079 vp->v_iflag &= ~VI_MOUNT; 1080 VI_UNLOCK(vp); 1081 vrele(vp); 1082 return (error != 0 ? error : export_error); 1083} 1084 1085/* 1086 * vfs_domount(): actually attempt a filesystem mount. 1087 */ 1088static int 1089vfs_domount( 1090 struct thread *td, /* Calling thread. */ 1091 const char *fstype, /* Filesystem type. */ 1092 char *fspath, /* Mount path. */ 1093 uint64_t fsflags, /* Flags common to all filesystems. */ 1094 struct vfsoptlist **optlist /* Options local to the filesystem. */ 1095 ) 1096{ 1097 struct vfsconf *vfsp; 1098 struct nameidata nd; 1099 struct vnode *vp; 1100 char *pathbuf; 1101 int error; 1102 1103 /* 1104 * Be ultra-paranoid about making sure the type and fspath 1105 * variables will fit in our mp buffers, including the 1106 * terminating NUL. 1107 */ 1108 if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN) 1109 return (ENAMETOOLONG); 1110 1111 if (jailed(td->td_ucred) || usermount == 0) { 1112 if ((error = priv_check(td, PRIV_VFS_MOUNT)) != 0) 1113 return (error); 1114 } 1115 1116 /* 1117 * Do not allow NFS export or MNT_SUIDDIR by unprivileged users. 1118 */ 1119 if (fsflags & MNT_EXPORTED) { 1120 error = priv_check(td, PRIV_VFS_MOUNT_EXPORTED); 1121 if (error) 1122 return (error); 1123 } 1124 if (fsflags & MNT_SUIDDIR) { 1125 error = priv_check(td, PRIV_VFS_MOUNT_SUIDDIR); 1126 if (error) 1127 return (error); 1128 } 1129 /* 1130 * Silently enforce MNT_NOSUID and MNT_USER for unprivileged users. 1131 */ 1132 if ((fsflags & (MNT_NOSUID | MNT_USER)) != (MNT_NOSUID | MNT_USER)) { 1133 if (priv_check(td, PRIV_VFS_MOUNT_NONUSER) != 0) 1134 fsflags |= MNT_NOSUID | MNT_USER; 1135 } 1136 1137 /* Load KLDs before we lock the covered vnode to avoid reversals. */ 1138 vfsp = NULL; 1139 if ((fsflags & MNT_UPDATE) == 0) { 1140 /* Don't try to load KLDs if we're mounting the root. */ 1141 if (fsflags & MNT_ROOTFS) 1142 vfsp = vfs_byname(fstype); 1143 else 1144 vfsp = vfs_byname_kld(fstype, td, &error); 1145 if (vfsp == NULL) 1146 return (ENODEV); 1147 if (jailed(td->td_ucred) && !(vfsp->vfc_flags & VFCF_JAIL)) 1148 return (EPERM); 1149 } 1150 1151 /* 1152 * Get vnode to be covered or mount point's vnode in case of MNT_UPDATE. 1153 */ 1154 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, 1155 UIO_SYSSPACE, fspath, td); 1156 error = namei(&nd); 1157 if (error != 0) 1158 return (error); 1159 NDFREE(&nd, NDF_ONLY_PNBUF); 1160 vp = nd.ni_vp; 1161 if ((fsflags & MNT_UPDATE) == 0) { 1162 pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK); 1163 strcpy(pathbuf, fspath); 1164 error = vn_path_to_global_path(td, vp, pathbuf, MNAMELEN); 1165 /* debug.disablefullpath == 1 results in ENODEV */ 1166 if (error == 0 || error == ENODEV) { 1167 error = vfs_domount_first(td, vfsp, pathbuf, vp, 1168 fsflags, optlist); 1169 } 1170 free(pathbuf, M_TEMP); 1171 } else 1172 error = vfs_domount_update(td, vp, fsflags, optlist); 1173 1174 return (error); 1175} 1176 1177/* 1178 * Unmount a filesystem. 1179 * 1180 * Note: unmount takes a path to the vnode mounted on as argument, not 1181 * special file (as before). 1182 */ 1183#ifndef _SYS_SYSPROTO_H_ 1184struct unmount_args { 1185 char *path; 1186 int flags; 1187}; 1188#endif 1189/* ARGSUSED */ 1190int 1191sys_unmount(struct thread *td, struct unmount_args *uap) 1192{ 1193 struct nameidata nd; 1194 struct mount *mp; 1195 char *pathbuf; 1196 int error, id0, id1; 1197 1198 AUDIT_ARG_VALUE(uap->flags); 1199 if (jailed(td->td_ucred) || usermount == 0) { 1200 error = priv_check(td, PRIV_VFS_UNMOUNT); 1201 if (error) 1202 return (error); 1203 } 1204 1205 pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK); 1206 error = copyinstr(uap->path, pathbuf, MNAMELEN, NULL); 1207 if (error) { 1208 free(pathbuf, M_TEMP); 1209 return (error); 1210 } 1211 if (uap->flags & MNT_BYFSID) { 1212 AUDIT_ARG_TEXT(pathbuf); 1213 /* Decode the filesystem ID. */ 1214 if (sscanf(pathbuf, "FSID:%d:%d", &id0, &id1) != 2) { 1215 free(pathbuf, M_TEMP); 1216 return (EINVAL); 1217 } 1218 1219 mtx_lock(&mountlist_mtx); 1220 TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { 1221 if (mp->mnt_stat.f_fsid.val[0] == id0 && 1222 mp->mnt_stat.f_fsid.val[1] == id1) { 1223 vfs_ref(mp); 1224 break; 1225 } 1226 } 1227 mtx_unlock(&mountlist_mtx); 1228 } else { 1229 /* 1230 * Try to find global path for path argument. 1231 */ 1232 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, 1233 UIO_SYSSPACE, pathbuf, td); 1234 if (namei(&nd) == 0) { 1235 NDFREE(&nd, NDF_ONLY_PNBUF); 1236 error = vn_path_to_global_path(td, nd.ni_vp, pathbuf, 1237 MNAMELEN); 1238 if (error == 0 || error == ENODEV) 1239 vput(nd.ni_vp); 1240 } 1241 mtx_lock(&mountlist_mtx); 1242 TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { 1243 if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0) { 1244 vfs_ref(mp); 1245 break; 1246 } 1247 } 1248 mtx_unlock(&mountlist_mtx); 1249 } 1250 free(pathbuf, M_TEMP); 1251 if (mp == NULL) { 1252 /* 1253 * Previously we returned ENOENT for a nonexistent path and 1254 * EINVAL for a non-mountpoint. We cannot tell these apart 1255 * now, so in the !MNT_BYFSID case return the more likely 1256 * EINVAL for compatibility. 1257 */ 1258 return ((uap->flags & MNT_BYFSID) ? ENOENT : EINVAL); 1259 } 1260 1261 /* 1262 * Don't allow unmounting the root filesystem. 1263 */ 1264 if (mp->mnt_flag & MNT_ROOTFS) { 1265 vfs_rel(mp); 1266 return (EINVAL); 1267 } 1268 error = dounmount(mp, uap->flags, td); 1269 return (error); 1270} 1271 1272/* 1273 * Do the actual filesystem unmount. 1274 */ 1275int 1276dounmount(struct mount *mp, int flags, struct thread *td) 1277{ 1278 struct vnode *coveredvp, *fsrootvp; 1279 int error; 1280 uint64_t async_flag; 1281 int mnt_gen_r; 1282 1283 if ((coveredvp = mp->mnt_vnodecovered) != NULL) { 1284 mnt_gen_r = mp->mnt_gen; 1285 VI_LOCK(coveredvp); 1286 vholdl(coveredvp); 1287 vn_lock(coveredvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_RETRY); 1288 /* 1289 * Check for mp being unmounted while waiting for the 1290 * covered vnode lock. 1291 */ 1292 if (coveredvp->v_mountedhere != mp || 1293 coveredvp->v_mountedhere->mnt_gen != mnt_gen_r) { 1294 VOP_UNLOCK(coveredvp, 0); 1295 vdrop(coveredvp); 1296 vfs_rel(mp); 1297 return (EBUSY); 1298 } 1299 } 1300 1301 /* 1302 * Only privileged root, or (if MNT_USER is set) the user that did the 1303 * original mount is permitted to unmount this filesystem. 1304 */ 1305 error = vfs_suser(mp, td); 1306 if (error != 0) { 1307 if (coveredvp != NULL) { 1308 VOP_UNLOCK(coveredvp, 0); 1309 vdrop(coveredvp); 1310 } 1311 vfs_rel(mp); 1312 return (error); 1313 } 1314 1315 vn_start_write(NULL, &mp, V_WAIT | V_MNTREF); 1316 MNT_ILOCK(mp); 1317 if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 || 1318 (mp->mnt_flag & MNT_UPDATE) != 0 || 1319 !TAILQ_EMPTY(&mp->mnt_uppers)) { 1320 MNT_IUNLOCK(mp); 1321 if (coveredvp != NULL) { 1322 VOP_UNLOCK(coveredvp, 0); 1323 vdrop(coveredvp); 1324 } 1325 vn_finished_write(mp); 1326 return (EBUSY); 1327 } 1328 mp->mnt_kern_flag |= MNTK_UNMOUNT | MNTK_NOINSMNTQ; 1329 /* Allow filesystems to detect that a forced unmount is in progress. */ 1330 if (flags & MNT_FORCE) { 1331 mp->mnt_kern_flag |= MNTK_UNMOUNTF; 1332 MNT_IUNLOCK(mp); 1333 /* 1334 * Must be done after setting MNTK_UNMOUNTF and before 1335 * waiting for mnt_lockref to become 0. 1336 */ 1337 VFS_PURGE(mp); 1338 MNT_ILOCK(mp); 1339 } 1340 error = 0; 1341 if (mp->mnt_lockref) { 1342 mp->mnt_kern_flag |= MNTK_DRAINING; 1343 error = msleep(&mp->mnt_lockref, MNT_MTX(mp), PVFS, 1344 "mount drain", 0); 1345 } 1346 MNT_IUNLOCK(mp); 1347 KASSERT(mp->mnt_lockref == 0, 1348 ("%s: invalid lock refcount in the drain path @ %s:%d", 1349 __func__, __FILE__, __LINE__)); 1350 KASSERT(error == 0, 1351 ("%s: invalid return value for msleep in the drain path @ %s:%d", 1352 __func__, __FILE__, __LINE__)); 1353 1354 if (mp->mnt_flag & MNT_EXPUBLIC) 1355 vfs_setpublicfs(NULL, NULL, NULL); 1356 1357 /* 1358 * From now, we can claim that the use reference on the 1359 * coveredvp is ours, and the ref can be released only by 1360 * successfull unmount by us, or left for later unmount 1361 * attempt. The previously acquired hold reference is no 1362 * longer needed to protect the vnode from reuse. 1363 */ 1364 if (coveredvp != NULL) 1365 vdrop(coveredvp); 1366 1367 vfs_msync(mp, MNT_WAIT); 1368 MNT_ILOCK(mp); 1369 async_flag = mp->mnt_flag & MNT_ASYNC; 1370 mp->mnt_flag &= ~MNT_ASYNC; 1371 mp->mnt_kern_flag &= ~MNTK_ASYNC; 1372 MNT_IUNLOCK(mp); 1373 cache_purgevfs(mp); /* remove cache entries for this file sys */ 1374 vfs_deallocate_syncvnode(mp); 1375 /* 1376 * For forced unmounts, move process cdir/rdir refs on the fs root 1377 * vnode to the covered vnode. For non-forced unmounts we want 1378 * such references to cause an EBUSY error. 1379 */ 1380 if ((flags & MNT_FORCE) && 1381 VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp) == 0) { 1382 if (mp->mnt_vnodecovered != NULL && 1383 (mp->mnt_flag & MNT_IGNORE) == 0) 1384 mountcheckdirs(fsrootvp, mp->mnt_vnodecovered); 1385 if (fsrootvp == rootvnode) { 1386 vrele(rootvnode); 1387 rootvnode = NULL; 1388 } 1389 vput(fsrootvp); 1390 } 1391 if ((mp->mnt_flag & MNT_RDONLY) != 0 || (flags & MNT_FORCE) != 0 || 1392 (error = VFS_SYNC(mp, MNT_WAIT)) == 0) 1393 error = VFS_UNMOUNT(mp, flags); 1394 vn_finished_write(mp); 1395 /* 1396 * If we failed to flush the dirty blocks for this mount point, 1397 * undo all the cdir/rdir and rootvnode changes we made above. 1398 * Unless we failed to do so because the device is reporting that 1399 * it doesn't exist anymore. 1400 */ 1401 if (error && error != ENXIO) { 1402 if ((flags & MNT_FORCE) && 1403 VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp) == 0) { 1404 if (mp->mnt_vnodecovered != NULL && 1405 (mp->mnt_flag & MNT_IGNORE) == 0) 1406 mountcheckdirs(mp->mnt_vnodecovered, fsrootvp); 1407 if (rootvnode == NULL) { 1408 rootvnode = fsrootvp; 1409 vref(rootvnode); 1410 } 1411 vput(fsrootvp); 1412 } 1413 MNT_ILOCK(mp); 1414 mp->mnt_kern_flag &= ~MNTK_NOINSMNTQ; 1415 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 1416 MNT_IUNLOCK(mp); 1417 vfs_allocate_syncvnode(mp); 1418 MNT_ILOCK(mp); 1419 } 1420 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF); 1421 mp->mnt_flag |= async_flag; 1422 if ((mp->mnt_flag & MNT_ASYNC) != 0 && 1423 (mp->mnt_kern_flag & MNTK_NOASYNC) == 0) 1424 mp->mnt_kern_flag |= MNTK_ASYNC; 1425 if (mp->mnt_kern_flag & MNTK_MWAIT) { 1426 mp->mnt_kern_flag &= ~MNTK_MWAIT; 1427 wakeup(mp); 1428 } 1429 MNT_IUNLOCK(mp); 1430 if (coveredvp) 1431 VOP_UNLOCK(coveredvp, 0); 1432 return (error); 1433 } 1434 mtx_lock(&mountlist_mtx); 1435 TAILQ_REMOVE(&mountlist, mp, mnt_list); 1436 mtx_unlock(&mountlist_mtx); 1437 EVENTHANDLER_INVOKE(vfs_unmounted, mp, td); 1438 if (coveredvp != NULL) { 1439 coveredvp->v_mountedhere = NULL; 1440 VOP_UNLOCK(coveredvp, 0); 1441 } 1442 vfs_event_signal(NULL, VQ_UNMOUNT, 0); 1443 if (mp == rootdevmp) 1444 rootdevmp = NULL; 1445 vfs_mount_destroy(mp); 1446 return (0); 1447} 1448 1449/* 1450 * Report errors during filesystem mounting. 1451 */ 1452void 1453vfs_mount_error(struct mount *mp, const char *fmt, ...) 1454{ 1455 struct vfsoptlist *moptlist = mp->mnt_optnew; 1456 va_list ap; 1457 int error, len; 1458 char *errmsg; 1459 1460 error = vfs_getopt(moptlist, "errmsg", (void **)&errmsg, &len); 1461 if (error || errmsg == NULL || len <= 0) 1462 return; 1463 1464 va_start(ap, fmt); 1465 vsnprintf(errmsg, (size_t)len, fmt, ap); 1466 va_end(ap); 1467} 1468 1469void 1470vfs_opterror(struct vfsoptlist *opts, const char *fmt, ...) 1471{ 1472 va_list ap; 1473 int error, len; 1474 char *errmsg; 1475 1476 error = vfs_getopt(opts, "errmsg", (void **)&errmsg, &len); 1477 if (error || errmsg == NULL || len <= 0) 1478 return; 1479 1480 va_start(ap, fmt); 1481 vsnprintf(errmsg, (size_t)len, fmt, ap); 1482 va_end(ap); 1483} 1484 1485/* 1486 * --------------------------------------------------------------------- 1487 * Functions for querying mount options/arguments from filesystems. 1488 */ 1489 1490/* 1491 * Check that no unknown options are given 1492 */ 1493int 1494vfs_filteropt(struct vfsoptlist *opts, const char **legal) 1495{ 1496 struct vfsopt *opt; 1497 char errmsg[255]; 1498 const char **t, *p, *q; 1499 int ret = 0; 1500 1501 TAILQ_FOREACH(opt, opts, link) { 1502 p = opt->name; 1503 q = NULL; 1504 if (p[0] == 'n' && p[1] == 'o') 1505 q = p + 2; 1506 for(t = global_opts; *t != NULL; t++) { 1507 if (strcmp(*t, p) == 0) 1508 break; 1509 if (q != NULL) { 1510 if (strcmp(*t, q) == 0) 1511 break; 1512 } 1513 } 1514 if (*t != NULL) 1515 continue; 1516 for(t = legal; *t != NULL; t++) { 1517 if (strcmp(*t, p) == 0) 1518 break; 1519 if (q != NULL) { 1520 if (strcmp(*t, q) == 0) 1521 break; 1522 } 1523 } 1524 if (*t != NULL) 1525 continue; 1526 snprintf(errmsg, sizeof(errmsg), 1527 "mount option <%s> is unknown", p); 1528 ret = EINVAL; 1529 } 1530 if (ret != 0) { 1531 TAILQ_FOREACH(opt, opts, link) { 1532 if (strcmp(opt->name, "errmsg") == 0) { 1533 strncpy((char *)opt->value, errmsg, opt->len); 1534 break; 1535 } 1536 } 1537 if (opt == NULL) 1538 printf("%s\n", errmsg); 1539 } 1540 return (ret); 1541} 1542 1543/* 1544 * Get a mount option by its name. 1545 * 1546 * Return 0 if the option was found, ENOENT otherwise. 1547 * If len is non-NULL it will be filled with the length 1548 * of the option. If buf is non-NULL, it will be filled 1549 * with the address of the option. 1550 */ 1551int 1552vfs_getopt(opts, name, buf, len) 1553 struct vfsoptlist *opts; 1554 const char *name; 1555 void **buf; 1556 int *len; 1557{ 1558 struct vfsopt *opt; 1559 1560 KASSERT(opts != NULL, ("vfs_getopt: caller passed 'opts' as NULL")); 1561 1562 TAILQ_FOREACH(opt, opts, link) { 1563 if (strcmp(name, opt->name) == 0) { 1564 opt->seen = 1; 1565 if (len != NULL) 1566 *len = opt->len; 1567 if (buf != NULL) 1568 *buf = opt->value; 1569 return (0); 1570 } 1571 } 1572 return (ENOENT); 1573} 1574 1575int 1576vfs_getopt_pos(struct vfsoptlist *opts, const char *name) 1577{ 1578 struct vfsopt *opt; 1579 1580 if (opts == NULL) 1581 return (-1); 1582 1583 TAILQ_FOREACH(opt, opts, link) { 1584 if (strcmp(name, opt->name) == 0) { 1585 opt->seen = 1; 1586 return (opt->pos); 1587 } 1588 } 1589 return (-1); 1590} 1591 1592int 1593vfs_getopt_size(struct vfsoptlist *opts, const char *name, off_t *value) 1594{ 1595 char *opt_value, *vtp; 1596 quad_t iv; 1597 int error, opt_len; 1598 1599 error = vfs_getopt(opts, name, (void **)&opt_value, &opt_len); 1600 if (error != 0) 1601 return (error); 1602 if (opt_len == 0 || opt_value == NULL) 1603 return (EINVAL); 1604 if (opt_value[0] == '\0' || opt_value[opt_len - 1] != '\0') 1605 return (EINVAL); 1606 iv = strtoq(opt_value, &vtp, 0); 1607 if (vtp == opt_value || (vtp[0] != '\0' && vtp[1] != '\0')) 1608 return (EINVAL); 1609 if (iv < 0) 1610 return (EINVAL); 1611 switch (vtp[0]) { 1612 case 't': 1613 case 'T': 1614 iv *= 1024; 1615 case 'g': 1616 case 'G': 1617 iv *= 1024; 1618 case 'm': 1619 case 'M': 1620 iv *= 1024; 1621 case 'k': 1622 case 'K': 1623 iv *= 1024; 1624 case '\0': 1625 break; 1626 default: 1627 return (EINVAL); 1628 } 1629 *value = iv; 1630 1631 return (0); 1632} 1633 1634char * 1635vfs_getopts(struct vfsoptlist *opts, const char *name, int *error) 1636{ 1637 struct vfsopt *opt; 1638 1639 *error = 0; 1640 TAILQ_FOREACH(opt, opts, link) { 1641 if (strcmp(name, opt->name) != 0) 1642 continue; 1643 opt->seen = 1; 1644 if (opt->len == 0 || 1645 ((char *)opt->value)[opt->len - 1] != '\0') { 1646 *error = EINVAL; 1647 return (NULL); 1648 } 1649 return (opt->value); 1650 } 1651 *error = ENOENT; 1652 return (NULL); 1653} 1654 1655int 1656vfs_flagopt(struct vfsoptlist *opts, const char *name, uint64_t *w, 1657 uint64_t val) 1658{ 1659 struct vfsopt *opt; 1660 1661 TAILQ_FOREACH(opt, opts, link) { 1662 if (strcmp(name, opt->name) == 0) { 1663 opt->seen = 1; 1664 if (w != NULL) 1665 *w |= val; 1666 return (1); 1667 } 1668 } 1669 if (w != NULL) 1670 *w &= ~val; 1671 return (0); 1672} 1673 1674int 1675vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...) 1676{ 1677 va_list ap; 1678 struct vfsopt *opt; 1679 int ret; 1680 1681 KASSERT(opts != NULL, ("vfs_getopt: caller passed 'opts' as NULL")); 1682 1683 TAILQ_FOREACH(opt, opts, link) { 1684 if (strcmp(name, opt->name) != 0) 1685 continue; 1686 opt->seen = 1; 1687 if (opt->len == 0 || opt->value == NULL) 1688 return (0); 1689 if (((char *)opt->value)[opt->len - 1] != '\0') 1690 return (0); 1691 va_start(ap, fmt); 1692 ret = vsscanf(opt->value, fmt, ap); 1693 va_end(ap); 1694 return (ret); 1695 } 1696 return (0); 1697} 1698 1699int 1700vfs_setopt(struct vfsoptlist *opts, const char *name, void *value, int len) 1701{ 1702 struct vfsopt *opt; 1703 1704 TAILQ_FOREACH(opt, opts, link) { 1705 if (strcmp(name, opt->name) != 0) 1706 continue; 1707 opt->seen = 1; 1708 if (opt->value == NULL) 1709 opt->len = len; 1710 else { 1711 if (opt->len != len) 1712 return (EINVAL); 1713 bcopy(value, opt->value, len); 1714 } 1715 return (0); 1716 } 1717 return (ENOENT); 1718} 1719 1720int 1721vfs_setopt_part(struct vfsoptlist *opts, const char *name, void *value, int len) 1722{ 1723 struct vfsopt *opt; 1724 1725 TAILQ_FOREACH(opt, opts, link) { 1726 if (strcmp(name, opt->name) != 0) 1727 continue; 1728 opt->seen = 1; 1729 if (opt->value == NULL) 1730 opt->len = len; 1731 else { 1732 if (opt->len < len) 1733 return (EINVAL); 1734 opt->len = len; 1735 bcopy(value, opt->value, len); 1736 } 1737 return (0); 1738 } 1739 return (ENOENT); 1740} 1741 1742int 1743vfs_setopts(struct vfsoptlist *opts, const char *name, const char *value) 1744{ 1745 struct vfsopt *opt; 1746 1747 TAILQ_FOREACH(opt, opts, link) { 1748 if (strcmp(name, opt->name) != 0) 1749 continue; 1750 opt->seen = 1; 1751 if (opt->value == NULL) 1752 opt->len = strlen(value) + 1; 1753 else if (strlcpy(opt->value, value, opt->len) >= opt->len) 1754 return (EINVAL); 1755 return (0); 1756 } 1757 return (ENOENT); 1758} 1759 1760/* 1761 * Find and copy a mount option. 1762 * 1763 * The size of the buffer has to be specified 1764 * in len, if it is not the same length as the 1765 * mount option, EINVAL is returned. 1766 * Returns ENOENT if the option is not found. 1767 */ 1768int 1769vfs_copyopt(opts, name, dest, len) 1770 struct vfsoptlist *opts; 1771 const char *name; 1772 void *dest; 1773 int len; 1774{ 1775 struct vfsopt *opt; 1776 1777 KASSERT(opts != NULL, ("vfs_copyopt: caller passed 'opts' as NULL")); 1778 1779 TAILQ_FOREACH(opt, opts, link) { 1780 if (strcmp(name, opt->name) == 0) { 1781 opt->seen = 1; 1782 if (len != opt->len) 1783 return (EINVAL); 1784 bcopy(opt->value, dest, opt->len); 1785 return (0); 1786 } 1787 } 1788 return (ENOENT); 1789} 1790 1791int 1792__vfs_statfs(struct mount *mp, struct statfs *sbp) 1793{ 1794 int error; 1795 1796 error = mp->mnt_op->vfs_statfs(mp, &mp->mnt_stat); 1797 if (sbp != &mp->mnt_stat) 1798 *sbp = mp->mnt_stat; 1799 return (error); 1800} 1801 1802void 1803vfs_mountedfrom(struct mount *mp, const char *from) 1804{ 1805 1806 bzero(mp->mnt_stat.f_mntfromname, sizeof mp->mnt_stat.f_mntfromname); 1807 strlcpy(mp->mnt_stat.f_mntfromname, from, 1808 sizeof mp->mnt_stat.f_mntfromname); 1809} 1810 1811/* 1812 * --------------------------------------------------------------------- 1813 * This is the api for building mount args and mounting filesystems from 1814 * inside the kernel. 1815 * 1816 * The API works by accumulation of individual args. First error is 1817 * latched. 1818 * 1819 * XXX: should be documented in new manpage kernel_mount(9) 1820 */ 1821 1822/* A memory allocation which must be freed when we are done */ 1823struct mntaarg { 1824 SLIST_ENTRY(mntaarg) next; 1825}; 1826 1827/* The header for the mount arguments */ 1828struct mntarg { 1829 struct iovec *v; 1830 int len; 1831 int error; 1832 SLIST_HEAD(, mntaarg) list; 1833}; 1834 1835/* 1836 * Add a boolean argument. 1837 * 1838 * flag is the boolean value. 1839 * name must start with "no". 1840 */ 1841struct mntarg * 1842mount_argb(struct mntarg *ma, int flag, const char *name) 1843{ 1844 1845 KASSERT(name[0] == 'n' && name[1] == 'o', 1846 ("mount_argb(...,%s): name must start with 'no'", name)); 1847 1848 return (mount_arg(ma, name + (flag ? 2 : 0), NULL, 0)); 1849} 1850 1851/* 1852 * Add an argument printf style 1853 */ 1854struct mntarg * 1855mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...) 1856{ 1857 va_list ap; 1858 struct mntaarg *maa; 1859 struct sbuf *sb; 1860 int len; 1861 1862 if (ma == NULL) { 1863 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO); 1864 SLIST_INIT(&ma->list); 1865 } 1866 if (ma->error) 1867 return (ma); 1868 1869 ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2), 1870 M_MOUNT, M_WAITOK); 1871 ma->v[ma->len].iov_base = (void *)(uintptr_t)name; 1872 ma->v[ma->len].iov_len = strlen(name) + 1; 1873 ma->len++; 1874 1875 sb = sbuf_new_auto(); 1876 va_start(ap, fmt); 1877 sbuf_vprintf(sb, fmt, ap); 1878 va_end(ap); 1879 sbuf_finish(sb); 1880 len = sbuf_len(sb) + 1; 1881 maa = malloc(sizeof *maa + len, M_MOUNT, M_WAITOK | M_ZERO); 1882 SLIST_INSERT_HEAD(&ma->list, maa, next); 1883 bcopy(sbuf_data(sb), maa + 1, len); 1884 sbuf_delete(sb); 1885 1886 ma->v[ma->len].iov_base = maa + 1; 1887 ma->v[ma->len].iov_len = len; 1888 ma->len++; 1889 1890 return (ma); 1891} 1892 1893/* 1894 * Add an argument which is a userland string. 1895 */ 1896struct mntarg * 1897mount_argsu(struct mntarg *ma, const char *name, const void *val, int len) 1898{ 1899 struct mntaarg *maa; 1900 char *tbuf; 1901 1902 if (val == NULL) 1903 return (ma); 1904 if (ma == NULL) { 1905 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO); 1906 SLIST_INIT(&ma->list); 1907 } 1908 if (ma->error) 1909 return (ma); 1910 maa = malloc(sizeof *maa + len, M_MOUNT, M_WAITOK | M_ZERO); 1911 SLIST_INSERT_HEAD(&ma->list, maa, next); 1912 tbuf = (void *)(maa + 1); 1913 ma->error = copyinstr(val, tbuf, len, NULL); 1914 return (mount_arg(ma, name, tbuf, -1)); 1915} 1916 1917/* 1918 * Plain argument. 1919 * 1920 * If length is -1, treat value as a C string. 1921 */ 1922struct mntarg * 1923mount_arg(struct mntarg *ma, const char *name, const void *val, int len) 1924{ 1925 1926 if (ma == NULL) { 1927 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO); 1928 SLIST_INIT(&ma->list); 1929 } 1930 if (ma->error) 1931 return (ma); 1932 1933 ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2), 1934 M_MOUNT, M_WAITOK); 1935 ma->v[ma->len].iov_base = (void *)(uintptr_t)name; 1936 ma->v[ma->len].iov_len = strlen(name) + 1; 1937 ma->len++; 1938 1939 ma->v[ma->len].iov_base = (void *)(uintptr_t)val; 1940 if (len < 0) 1941 ma->v[ma->len].iov_len = strlen(val) + 1; 1942 else 1943 ma->v[ma->len].iov_len = len; 1944 ma->len++; 1945 return (ma); 1946} 1947 1948/* 1949 * Free a mntarg structure 1950 */ 1951static void 1952free_mntarg(struct mntarg *ma) 1953{ 1954 struct mntaarg *maa; 1955 1956 while (!SLIST_EMPTY(&ma->list)) { 1957 maa = SLIST_FIRST(&ma->list); 1958 SLIST_REMOVE_HEAD(&ma->list, next); 1959 free(maa, M_MOUNT); 1960 } 1961 free(ma->v, M_MOUNT); 1962 free(ma, M_MOUNT); 1963} 1964 1965/* 1966 * Mount a filesystem 1967 */ 1968int 1969kernel_mount(struct mntarg *ma, uint64_t flags) 1970{ 1971 struct uio auio; 1972 int error; 1973 1974 KASSERT(ma != NULL, ("kernel_mount NULL ma")); 1975 KASSERT(ma->v != NULL, ("kernel_mount NULL ma->v")); 1976 KASSERT(!(ma->len & 1), ("kernel_mount odd ma->len (%d)", ma->len)); 1977 1978 auio.uio_iov = ma->v; 1979 auio.uio_iovcnt = ma->len; 1980 auio.uio_segflg = UIO_SYSSPACE; 1981 1982 error = ma->error; 1983 if (!error) 1984 error = vfs_donmount(curthread, flags, &auio); 1985 free_mntarg(ma); 1986 return (error); 1987} 1988 1989/* 1990 * A printflike function to mount a filesystem. 1991 */ 1992int 1993kernel_vmount(int flags, ...) 1994{ 1995 struct mntarg *ma = NULL; 1996 va_list ap; 1997 const char *cp; 1998 const void *vp; 1999 int error; 2000 2001 va_start(ap, flags); 2002 for (;;) { 2003 cp = va_arg(ap, const char *); 2004 if (cp == NULL) 2005 break; 2006 vp = va_arg(ap, const void *); 2007 ma = mount_arg(ma, cp, vp, (vp != NULL ? -1 : 0)); 2008 } 2009 va_end(ap); 2010 2011 error = kernel_mount(ma, flags); 2012 return (error); 2013} 2014 2015void 2016vfs_oexport_conv(const struct oexport_args *oexp, struct export_args *exp) 2017{ 2018 2019 bcopy(oexp, exp, sizeof(*oexp)); 2020 exp->ex_numsecflavors = 0; 2021} 2022