2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 1999-2004 Poul-Henning Kamp
5 * Copyright (c) 1999 Michael Smith
6 * Copyright (c) 1989, 1993
7 * The Regents of the University of California. All rights reserved.
8 * (c) UNIX System Laboratories, Inc.
9 * All or some portions of this file are derived from material licensed
10 * to the University of California by American Telephone and Telegraph
11 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
12 * the permission of UNIX System Laboratories, Inc.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD$");
42 #include <sys/param.h>
44 #include <sys/eventhandler.h>
45 #include <sys/fcntl.h>
47 #include <sys/kernel.h>
48 #include <sys/libkern.h>
49 #include <sys/malloc.h>
50 #include <sys/mount.h>
51 #include <sys/mutex.h>
52 #include <sys/namei.h>
55 #include <sys/filedesc.h>
56 #include <sys/reboot.h>
58 #include <sys/syscallsubr.h>
59 #include <sys/sysproto.h>
61 #include <sys/sysctl.h>
62 #include <sys/sysent.h>
63 #include <sys/systm.h>
64 #include <sys/vnode.h>
67 #include <geom/geom.h>
69 #include <machine/stdarg.h>
71 #include <security/audit/audit.h>
72 #include <security/mac/mac_framework.h>
74 #define VFS_MOUNTARG_SIZE_MAX (1024 * 64)
76 static int vfs_domount(struct thread *td, const char *fstype, char *fspath,
77 uint64_t fsflags, struct vfsoptlist **optlist);
78 static void free_mntarg(struct mntarg *ma);
80 static int usermount = 0;
81 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0,
82 "Unprivileged users may mount and unmount file systems");
84 MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure");
85 MALLOC_DEFINE(M_STATFS, "statfs", "statfs structure");
86 static uma_zone_t mount_zone;
88 /* List of mounted filesystems. */
89 struct mntlist mountlist = TAILQ_HEAD_INITIALIZER(mountlist);
91 /* For any iteration/modification of mountlist */
92 struct mtx mountlist_mtx;
93 MTX_SYSINIT(mountlist, &mountlist_mtx, "mountlist", MTX_DEF);
95 EVENTHANDLER_LIST_DEFINE(vfs_mounted);
96 EVENTHANDLER_LIST_DEFINE(vfs_unmounted);
99 * Global opts, taken by all filesystems
101 static const char *global_opts[] = {
113 mount_init(void *mem, int size, int flags)
117 mp = (struct mount *)mem;
118 mtx_init(&mp->mnt_mtx, "struct mount mtx", NULL, MTX_DEF);
119 mtx_init(&mp->mnt_listmtx, "struct mount vlist mtx", NULL, MTX_DEF);
120 lockinit(&mp->mnt_explock, PVFS, "explock", 0, 0);
125 mount_fini(void *mem, int size)
129 mp = (struct mount *)mem;
130 lockdestroy(&mp->mnt_explock);
131 mtx_destroy(&mp->mnt_listmtx);
132 mtx_destroy(&mp->mnt_mtx);
136 vfs_mount_init(void *dummy __unused)
139 mount_zone = uma_zcreate("Mountpoints", sizeof(struct mount), NULL,
140 NULL, mount_init, mount_fini, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
142 SYSINIT(vfs_mount, SI_SUB_VFS, SI_ORDER_ANY, vfs_mount_init, NULL);
145 * ---------------------------------------------------------------------
146 * Functions for building and sanitizing the mount options
149 /* Remove one mount option. */
151 vfs_freeopt(struct vfsoptlist *opts, struct vfsopt *opt)
154 TAILQ_REMOVE(opts, opt, link);
155 free(opt->name, M_MOUNT);
156 if (opt->value != NULL)
157 free(opt->value, M_MOUNT);
161 /* Release all resources related to the mount options. */
163 vfs_freeopts(struct vfsoptlist *opts)
167 while (!TAILQ_EMPTY(opts)) {
168 opt = TAILQ_FIRST(opts);
169 vfs_freeopt(opts, opt);
175 vfs_deleteopt(struct vfsoptlist *opts, const char *name)
177 struct vfsopt *opt, *temp;
181 TAILQ_FOREACH_SAFE(opt, opts, link, temp) {
182 if (strcmp(opt->name, name) == 0)
183 vfs_freeopt(opts, opt);
188 vfs_isopt_ro(const char *opt)
191 if (strcmp(opt, "ro") == 0 || strcmp(opt, "rdonly") == 0 ||
192 strcmp(opt, "norw") == 0)
198 vfs_isopt_rw(const char *opt)
201 if (strcmp(opt, "rw") == 0 || strcmp(opt, "noro") == 0)
207 * Check if options are equal (with or without the "no" prefix).
210 vfs_equalopts(const char *opt1, const char *opt2)
214 /* "opt" vs. "opt" or "noopt" vs. "noopt" */
215 if (strcmp(opt1, opt2) == 0)
217 /* "noopt" vs. "opt" */
218 if (strncmp(opt1, "no", 2) == 0 && strcmp(opt1 + 2, opt2) == 0)
220 /* "opt" vs. "noopt" */
221 if (strncmp(opt2, "no", 2) == 0 && strcmp(opt1, opt2 + 2) == 0)
223 while ((p = strchr(opt1, '.')) != NULL &&
224 !strncmp(opt1, opt2, ++p - opt1)) {
227 /* "foo.noopt" vs. "foo.opt" */
228 if (strncmp(opt1, "no", 2) == 0 && strcmp(opt1 + 2, opt2) == 0)
230 /* "foo.opt" vs. "foo.noopt" */
231 if (strncmp(opt2, "no", 2) == 0 && strcmp(opt1, opt2 + 2) == 0)
234 /* "ro" / "rdonly" / "norw" / "rw" / "noro" */
235 if ((vfs_isopt_ro(opt1) || vfs_isopt_rw(opt1)) &&
236 (vfs_isopt_ro(opt2) || vfs_isopt_rw(opt2)))
242 * If a mount option is specified several times,
243 * (with or without the "no" prefix) only keep
244 * the last occurrence of it.
247 vfs_sanitizeopts(struct vfsoptlist *opts)
249 struct vfsopt *opt, *opt2, *tmp;
251 TAILQ_FOREACH_REVERSE(opt, opts, vfsoptlist, link) {
252 opt2 = TAILQ_PREV(opt, vfsoptlist, link);
253 while (opt2 != NULL) {
254 if (vfs_equalopts(opt->name, opt2->name)) {
255 tmp = TAILQ_PREV(opt2, vfsoptlist, link);
256 vfs_freeopt(opts, opt2);
259 opt2 = TAILQ_PREV(opt2, vfsoptlist, link);
266 * Build a linked list of mount options from a struct uio.
269 vfs_buildopts(struct uio *auio, struct vfsoptlist **options)
271 struct vfsoptlist *opts;
273 size_t memused, namelen, optlen;
274 unsigned int i, iovcnt;
277 opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK);
280 iovcnt = auio->uio_iovcnt;
281 for (i = 0; i < iovcnt; i += 2) {
282 namelen = auio->uio_iov[i].iov_len;
283 optlen = auio->uio_iov[i + 1].iov_len;
284 memused += sizeof(struct vfsopt) + optlen + namelen;
286 * Avoid consuming too much memory, and attempts to overflow
289 if (memused > VFS_MOUNTARG_SIZE_MAX ||
290 optlen > VFS_MOUNTARG_SIZE_MAX ||
291 namelen > VFS_MOUNTARG_SIZE_MAX) {
296 opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK);
297 opt->name = malloc(namelen, M_MOUNT, M_WAITOK);
304 * Do this early, so jumps to "bad" will free the current
307 TAILQ_INSERT_TAIL(opts, opt, link);
309 if (auio->uio_segflg == UIO_SYSSPACE) {
310 bcopy(auio->uio_iov[i].iov_base, opt->name, namelen);
312 error = copyin(auio->uio_iov[i].iov_base, opt->name,
317 /* Ensure names are null-terminated strings. */
318 if (namelen == 0 || opt->name[namelen - 1] != '\0') {
324 opt->value = malloc(optlen, M_MOUNT, M_WAITOK);
325 if (auio->uio_segflg == UIO_SYSSPACE) {
326 bcopy(auio->uio_iov[i + 1].iov_base, opt->value,
329 error = copyin(auio->uio_iov[i + 1].iov_base,
336 vfs_sanitizeopts(opts);
345 * Merge the old mount options with the new ones passed
346 * in the MNT_UPDATE case.
348 * XXX: This function will keep a "nofoo" option in the new
349 * options. E.g, if the option's canonical name is "foo",
350 * "nofoo" ends up in the mount point's active options.
353 vfs_mergeopts(struct vfsoptlist *toopts, struct vfsoptlist *oldopts)
355 struct vfsopt *opt, *new;
357 TAILQ_FOREACH(opt, oldopts, link) {
358 new = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK);
359 new->name = strdup(opt->name, M_MOUNT);
361 new->value = malloc(opt->len, M_MOUNT, M_WAITOK);
362 bcopy(opt->value, new->value, opt->len);
366 new->seen = opt->seen;
367 TAILQ_INSERT_HEAD(toopts, new, link);
369 vfs_sanitizeopts(toopts);
373 * Mount a filesystem.
375 #ifndef _SYS_SYSPROTO_H_
383 sys_nmount(struct thread *td, struct nmount_args *uap)
391 * Mount flags are now 64-bits. On 32-bit archtectures only
392 * 32-bits are passed in, but from here on everything handles
393 * 64-bit flags correctly.
397 AUDIT_ARG_FFLAGS(flags);
398 CTR4(KTR_VFS, "%s: iovp %p with iovcnt %d and flags %d", __func__,
399 uap->iovp, uap->iovcnt, flags);
402 * Filter out MNT_ROOTFS. We do not want clients of nmount() in
403 * userspace to set this flag, but we must filter it out if we want
404 * MNT_UPDATE on the root file system to work.
405 * MNT_ROOTFS should only be set by the kernel when mounting its
408 flags &= ~MNT_ROOTFS;
410 iovcnt = uap->iovcnt;
412 * Check that we have an even number of iovec's
413 * and that we have at least two options.
415 if ((iovcnt & 1) || (iovcnt < 4)) {
416 CTR2(KTR_VFS, "%s: failed for invalid iovcnt %d", __func__,
421 error = copyinuio(uap->iovp, iovcnt, &auio);
423 CTR2(KTR_VFS, "%s: failed for invalid uio op with %d errno",
427 error = vfs_donmount(td, flags, auio);
434 * ---------------------------------------------------------------------
435 * Various utility functions
439 vfs_ref(struct mount *mp)
442 CTR2(KTR_VFS, "%s: mp %p", __func__, mp);
449 vfs_rel(struct mount *mp)
452 CTR2(KTR_VFS, "%s: mp %p", __func__, mp);
459 * Allocate and initialize the mount point struct.
462 vfs_mount_alloc(struct vnode *vp, struct vfsconf *vfsp, const char *fspath,
467 mp = uma_zalloc(mount_zone, M_WAITOK);
468 bzero(&mp->mnt_startzero,
469 __rangeof(struct mount, mnt_startzero, mnt_endzero));
470 TAILQ_INIT(&mp->mnt_nvnodelist);
471 mp->mnt_nvnodelistsize = 0;
472 TAILQ_INIT(&mp->mnt_activevnodelist);
473 mp->mnt_activevnodelistsize = 0;
474 TAILQ_INIT(&mp->mnt_tmpfreevnodelist);
475 mp->mnt_tmpfreevnodelistsize = 0;
477 (void) vfs_busy(mp, MBF_NOWAIT);
478 atomic_add_acq_int(&vfsp->vfc_refcount, 1);
479 mp->mnt_op = vfsp->vfc_vfsops;
481 mp->mnt_stat.f_type = vfsp->vfc_typenum;
483 strlcpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
484 mp->mnt_vnodecovered = vp;
485 mp->mnt_cred = crdup(cred);
486 mp->mnt_stat.f_owner = cred->cr_uid;
487 strlcpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN);
488 mp->mnt_iosize_max = DFLTPHYS;
491 mac_mount_create(cred, mp);
493 arc4rand(&mp->mnt_hashseed, sizeof mp->mnt_hashseed, 0);
494 TAILQ_INIT(&mp->mnt_uppers);
499 * Destroy the mount struct previously allocated by vfs_mount_alloc().
502 vfs_mount_destroy(struct mount *mp)
506 mp->mnt_kern_flag |= MNTK_REFEXPIRE;
507 if (mp->mnt_kern_flag & MNTK_MWAIT) {
508 mp->mnt_kern_flag &= ~MNTK_MWAIT;
512 msleep(mp, MNT_MTX(mp), PVFS, "mntref", 0);
513 KASSERT(mp->mnt_ref == 0,
514 ("%s: invalid refcount in the drain path @ %s:%d", __func__,
515 __FILE__, __LINE__));
516 if (mp->mnt_writeopcount != 0)
517 panic("vfs_mount_destroy: nonzero writeopcount");
518 if (mp->mnt_secondary_writes != 0)
519 panic("vfs_mount_destroy: nonzero secondary_writes");
520 atomic_subtract_rel_int(&mp->mnt_vfc->vfc_refcount, 1);
521 if (!TAILQ_EMPTY(&mp->mnt_nvnodelist)) {
524 TAILQ_FOREACH(vp, &mp->mnt_nvnodelist, v_nmntvnodes)
525 vn_printf(vp, "dangling vnode ");
526 panic("unmount: dangling vnode");
528 KASSERT(TAILQ_EMPTY(&mp->mnt_uppers), ("mnt_uppers"));
529 if (mp->mnt_nvnodelistsize != 0)
530 panic("vfs_mount_destroy: nonzero nvnodelistsize");
531 if (mp->mnt_activevnodelistsize != 0)
532 panic("vfs_mount_destroy: nonzero activevnodelistsize");
533 if (mp->mnt_tmpfreevnodelistsize != 0)
534 panic("vfs_mount_destroy: nonzero tmpfreevnodelistsize");
535 if (mp->mnt_lockref != 0)
536 panic("vfs_mount_destroy: nonzero lock refcount");
538 if (mp->mnt_vnodecovered != NULL)
539 vrele(mp->mnt_vnodecovered);
541 mac_mount_destroy(mp);
543 if (mp->mnt_opt != NULL)
544 vfs_freeopts(mp->mnt_opt);
545 crfree(mp->mnt_cred);
546 uma_zfree(mount_zone, mp);
550 vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions)
552 struct vfsoptlist *optlist;
553 struct vfsopt *opt, *tmp_opt;
554 char *fstype, *fspath, *errmsg;
555 int error, fstypelen, fspathlen, errmsg_len, errmsg_pos;
557 errmsg = fspath = NULL;
558 errmsg_len = fspathlen = 0;
561 error = vfs_buildopts(fsoptions, &optlist);
565 if (vfs_getopt(optlist, "errmsg", (void **)&errmsg, &errmsg_len) == 0)
566 errmsg_pos = vfs_getopt_pos(optlist, "errmsg");
569 * We need these two options before the others,
570 * and they are mandatory for any filesystem.
571 * Ensure they are NUL terminated as well.
574 error = vfs_getopt(optlist, "fstype", (void **)&fstype, &fstypelen);
575 if (error || fstype[fstypelen - 1] != '\0') {
578 strncpy(errmsg, "Invalid fstype", errmsg_len);
582 error = vfs_getopt(optlist, "fspath", (void **)&fspath, &fspathlen);
583 if (error || fspath[fspathlen - 1] != '\0') {
586 strncpy(errmsg, "Invalid fspath", errmsg_len);
591 * We need to see if we have the "update" option
592 * before we call vfs_domount(), since vfs_domount() has special
593 * logic based on MNT_UPDATE. This is very important
594 * when we want to update the root filesystem.
596 TAILQ_FOREACH_SAFE(opt, optlist, link, tmp_opt) {
597 if (strcmp(opt->name, "update") == 0) {
598 fsflags |= MNT_UPDATE;
599 vfs_freeopt(optlist, opt);
601 else if (strcmp(opt->name, "async") == 0)
602 fsflags |= MNT_ASYNC;
603 else if (strcmp(opt->name, "force") == 0) {
604 fsflags |= MNT_FORCE;
605 vfs_freeopt(optlist, opt);
607 else if (strcmp(opt->name, "reload") == 0) {
608 fsflags |= MNT_RELOAD;
609 vfs_freeopt(optlist, opt);
611 else if (strcmp(opt->name, "multilabel") == 0)
612 fsflags |= MNT_MULTILABEL;
613 else if (strcmp(opt->name, "noasync") == 0)
614 fsflags &= ~MNT_ASYNC;
615 else if (strcmp(opt->name, "noatime") == 0)
616 fsflags |= MNT_NOATIME;
617 else if (strcmp(opt->name, "atime") == 0) {
618 free(opt->name, M_MOUNT);
619 opt->name = strdup("nonoatime", M_MOUNT);
621 else if (strcmp(opt->name, "noclusterr") == 0)
622 fsflags |= MNT_NOCLUSTERR;
623 else if (strcmp(opt->name, "clusterr") == 0) {
624 free(opt->name, M_MOUNT);
625 opt->name = strdup("nonoclusterr", M_MOUNT);
627 else if (strcmp(opt->name, "noclusterw") == 0)
628 fsflags |= MNT_NOCLUSTERW;
629 else if (strcmp(opt->name, "clusterw") == 0) {
630 free(opt->name, M_MOUNT);
631 opt->name = strdup("nonoclusterw", M_MOUNT);
633 else if (strcmp(opt->name, "noexec") == 0)
634 fsflags |= MNT_NOEXEC;
635 else if (strcmp(opt->name, "exec") == 0) {
636 free(opt->name, M_MOUNT);
637 opt->name = strdup("nonoexec", M_MOUNT);
639 else if (strcmp(opt->name, "nosuid") == 0)
640 fsflags |= MNT_NOSUID;
641 else if (strcmp(opt->name, "suid") == 0) {
642 free(opt->name, M_MOUNT);
643 opt->name = strdup("nonosuid", M_MOUNT);
645 else if (strcmp(opt->name, "nosymfollow") == 0)
646 fsflags |= MNT_NOSYMFOLLOW;
647 else if (strcmp(opt->name, "symfollow") == 0) {
648 free(opt->name, M_MOUNT);
649 opt->name = strdup("nonosymfollow", M_MOUNT);
651 else if (strcmp(opt->name, "noro") == 0)
652 fsflags &= ~MNT_RDONLY;
653 else if (strcmp(opt->name, "rw") == 0)
654 fsflags &= ~MNT_RDONLY;
655 else if (strcmp(opt->name, "ro") == 0)
656 fsflags |= MNT_RDONLY;
657 else if (strcmp(opt->name, "rdonly") == 0) {
658 free(opt->name, M_MOUNT);
659 opt->name = strdup("ro", M_MOUNT);
660 fsflags |= MNT_RDONLY;
662 else if (strcmp(opt->name, "suiddir") == 0)
663 fsflags |= MNT_SUIDDIR;
664 else if (strcmp(opt->name, "sync") == 0)
665 fsflags |= MNT_SYNCHRONOUS;
666 else if (strcmp(opt->name, "union") == 0)
667 fsflags |= MNT_UNION;
668 else if (strcmp(opt->name, "automounted") == 0) {
669 fsflags |= MNT_AUTOMOUNTED;
670 vfs_freeopt(optlist, opt);
675 * Be ultra-paranoid about making sure the type and fspath
676 * variables will fit in our mp buffers, including the
679 if (fstypelen > MFSNAMELEN || fspathlen > MNAMELEN) {
680 error = ENAMETOOLONG;
684 error = vfs_domount(td, fstype, fspath, fsflags, &optlist);
686 /* copyout the errmsg */
687 if (errmsg_pos != -1 && ((2 * errmsg_pos + 1) < fsoptions->uio_iovcnt)
688 && errmsg_len > 0 && errmsg != NULL) {
689 if (fsoptions->uio_segflg == UIO_SYSSPACE) {
691 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_base,
692 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_len);
695 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_base,
696 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_len);
701 vfs_freeopts(optlist);
708 #ifndef _SYS_SYSPROTO_H_
718 sys_mount(struct thread *td, struct mount_args *uap)
721 struct vfsconf *vfsp = NULL;
722 struct mntarg *ma = NULL;
727 * Mount flags are now 64-bits. On 32-bit architectures only
728 * 32-bits are passed in, but from here on everything handles
729 * 64-bit flags correctly.
733 AUDIT_ARG_FFLAGS(flags);
736 * Filter out MNT_ROOTFS. We do not want clients of mount() in
737 * userspace to set this flag, but we must filter it out if we want
738 * MNT_UPDATE on the root file system to work.
739 * MNT_ROOTFS should only be set by the kernel when mounting its
742 flags &= ~MNT_ROOTFS;
744 fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK);
745 error = copyinstr(uap->type, fstype, MFSNAMELEN, NULL);
747 free(fstype, M_TEMP);
751 AUDIT_ARG_TEXT(fstype);
752 vfsp = vfs_byname_kld(fstype, td, &error);
753 free(fstype, M_TEMP);
756 if (vfsp->vfc_vfsops->vfs_cmount == NULL)
759 ma = mount_argsu(ma, "fstype", uap->type, MFSNAMELEN);
760 ma = mount_argsu(ma, "fspath", uap->path, MNAMELEN);
761 ma = mount_argb(ma, flags & MNT_RDONLY, "noro");
762 ma = mount_argb(ma, !(flags & MNT_NOSUID), "nosuid");
763 ma = mount_argb(ma, !(flags & MNT_NOEXEC), "noexec");
765 error = vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, flags);
770 * vfs_domount_first(): first file system mount (not update)
774 struct thread *td, /* Calling thread. */
775 struct vfsconf *vfsp, /* File system type. */
776 char *fspath, /* Mount path. */
777 struct vnode *vp, /* Vnode to be covered. */
778 uint64_t fsflags, /* Flags common to all filesystems. */
779 struct vfsoptlist **optlist /* Options local to the filesystem. */
787 ASSERT_VOP_ELOCKED(vp, __func__);
788 KASSERT((fsflags & MNT_UPDATE) == 0, ("MNT_UPDATE shouldn't be here"));
791 * If the user is not root, ensure that they own the directory
792 * onto which we are attempting to mount.
794 error = VOP_GETATTR(vp, &va, td->td_ucred);
795 if (error == 0 && va.va_uid != td->td_ucred->cr_uid)
796 error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN, 0);
798 error = vinvalbuf(vp, V_SAVE, 0, 0);
799 if (error == 0 && vp->v_type != VDIR)
803 if ((vp->v_iflag & VI_MOUNT) == 0 && vp->v_mountedhere == NULL)
804 vp->v_iflag |= VI_MOUNT;
815 /* Allocate and initialize the filesystem. */
816 mp = vfs_mount_alloc(vp, vfsp, fspath, td->td_ucred);
817 /* XXXMAC: pass to vfs_mount_alloc? */
818 mp->mnt_optnew = *optlist;
819 /* Set the mount level flags. */
820 mp->mnt_flag = (fsflags & (MNT_UPDATEMASK | MNT_ROOTFS | MNT_RDONLY));
823 * Mount the filesystem.
824 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
825 * get. No freeing of cn_pnbuf.
827 error = VFS_MOUNT(mp);
830 mp->mnt_vnodecovered = NULL;
831 vfs_mount_destroy(mp);
833 vp->v_iflag &= ~VI_MOUNT;
839 if (mp->mnt_opt != NULL)
840 vfs_freeopts(mp->mnt_opt);
841 mp->mnt_opt = mp->mnt_optnew;
843 (void)VFS_STATFS(mp, &mp->mnt_stat);
846 * Prevent external consumers of mount options from reading mnt_optnew.
848 mp->mnt_optnew = NULL;
851 if ((mp->mnt_flag & MNT_ASYNC) != 0 &&
852 (mp->mnt_kern_flag & MNTK_NOASYNC) == 0)
853 mp->mnt_kern_flag |= MNTK_ASYNC;
855 mp->mnt_kern_flag &= ~MNTK_ASYNC;
858 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
861 vp->v_iflag &= ~VI_MOUNT;
863 vp->v_mountedhere = mp;
864 /* Place the new filesystem at the end of the mount list. */
865 mtx_lock(&mountlist_mtx);
866 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
867 mtx_unlock(&mountlist_mtx);
868 vfs_event_signal(NULL, VQ_MOUNT, 0);
869 if (VFS_ROOT(mp, LK_EXCLUSIVE, &newdp))
870 panic("mount: lost mount");
872 EVENTHANDLER_DIRECT_INVOKE(vfs_mounted, mp, newdp, td);
873 VOP_UNLOCK(newdp, 0);
874 mountcheckdirs(vp, newdp);
876 if ((mp->mnt_flag & MNT_RDONLY) == 0)
877 vfs_allocate_syncvnode(mp);
883 * vfs_domount_update(): update of mounted file system
887 struct thread *td, /* Calling thread. */
888 struct vnode *vp, /* Mount point vnode. */
889 uint64_t fsflags, /* Flags common to all filesystems. */
890 struct vfsoptlist **optlist /* Options local to the filesystem. */
893 struct export_args export;
896 int error, export_error, len;
899 ASSERT_VOP_ELOCKED(vp, __func__);
900 KASSERT((fsflags & MNT_UPDATE) != 0, ("MNT_UPDATE should be here"));
903 if ((vp->v_vflag & VV_ROOT) == 0) {
904 if (vfs_copyopt(*optlist, "export", &export, sizeof(export))
914 * We only allow the filesystem to be reloaded if it
915 * is currently mounted read-only.
918 if ((fsflags & MNT_RELOAD) != 0 && (flag & MNT_RDONLY) == 0) {
920 return (EOPNOTSUPP); /* Needs translation */
923 * Only privileged root, or (if MNT_USER is set) the user that
924 * did the original mount is permitted to update it.
926 error = vfs_suser(mp, td);
931 if (vfs_busy(mp, MBF_NOWAIT)) {
936 if ((vp->v_iflag & VI_MOUNT) != 0 || vp->v_mountedhere != NULL) {
942 vp->v_iflag |= VI_MOUNT;
947 if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0) {
952 mp->mnt_flag &= ~MNT_UPDATEMASK;
953 mp->mnt_flag |= fsflags & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE |
954 MNT_SNAPSHOT | MNT_ROOTFS | MNT_UPDATEMASK | MNT_RDONLY);
955 if ((mp->mnt_flag & MNT_ASYNC) == 0)
956 mp->mnt_kern_flag &= ~MNTK_ASYNC;
958 mp->mnt_optnew = *optlist;
959 vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt);
962 * Mount the filesystem.
963 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
964 * get. No freeing of cn_pnbuf.
966 error = VFS_MOUNT(mp);
969 /* Process the export option. */
970 if (error == 0 && vfs_getopt(mp->mnt_optnew, "export", &bufp,
972 /* Assume that there is only 1 ABI for each length. */
974 case (sizeof(struct oexport_args)):
975 bzero(&export, sizeof(export));
977 case (sizeof(export)):
978 bcopy(bufp, &export, len);
979 export_error = vfs_export(mp, &export);
982 export_error = EINVAL;
989 mp->mnt_flag &= ~(MNT_UPDATE | MNT_RELOAD | MNT_FORCE |
993 * If we fail, restore old mount flags. MNT_QUOTA is special,
994 * because it is not part of MNT_UPDATEMASK, but it could have
995 * changed in the meantime if quotactl(2) was called.
996 * All in all we want current value of MNT_QUOTA, not the old
999 mp->mnt_flag = (mp->mnt_flag & MNT_QUOTA) | (flag & ~MNT_QUOTA);
1001 if ((mp->mnt_flag & MNT_ASYNC) != 0 &&
1002 (mp->mnt_kern_flag & MNTK_NOASYNC) == 0)
1003 mp->mnt_kern_flag |= MNTK_ASYNC;
1005 mp->mnt_kern_flag &= ~MNTK_ASYNC;
1011 if (mp->mnt_opt != NULL)
1012 vfs_freeopts(mp->mnt_opt);
1013 mp->mnt_opt = mp->mnt_optnew;
1015 (void)VFS_STATFS(mp, &mp->mnt_stat);
1017 * Prevent external consumers of mount options from reading
1020 mp->mnt_optnew = NULL;
1022 if ((mp->mnt_flag & MNT_RDONLY) == 0)
1023 vfs_allocate_syncvnode(mp);
1025 vfs_deallocate_syncvnode(mp);
1029 vp->v_iflag &= ~VI_MOUNT;
1032 return (error != 0 ? error : export_error);
1036 * vfs_domount(): actually attempt a filesystem mount.
1040 struct thread *td, /* Calling thread. */
1041 const char *fstype, /* Filesystem type. */
1042 char *fspath, /* Mount path. */
1043 uint64_t fsflags, /* Flags common to all filesystems. */
1044 struct vfsoptlist **optlist /* Options local to the filesystem. */
1047 struct vfsconf *vfsp;
1048 struct nameidata nd;
1054 * Be ultra-paranoid about making sure the type and fspath
1055 * variables will fit in our mp buffers, including the
1058 if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN)
1059 return (ENAMETOOLONG);
1061 if (jailed(td->td_ucred) || usermount == 0) {
1062 if ((error = priv_check(td, PRIV_VFS_MOUNT)) != 0)
1067 * Do not allow NFS export or MNT_SUIDDIR by unprivileged users.
1069 if (fsflags & MNT_EXPORTED) {
1070 error = priv_check(td, PRIV_VFS_MOUNT_EXPORTED);
1074 if (fsflags & MNT_SUIDDIR) {
1075 error = priv_check(td, PRIV_VFS_MOUNT_SUIDDIR);
1080 * Silently enforce MNT_NOSUID and MNT_USER for unprivileged users.
1082 if ((fsflags & (MNT_NOSUID | MNT_USER)) != (MNT_NOSUID | MNT_USER)) {
1083 if (priv_check(td, PRIV_VFS_MOUNT_NONUSER) != 0)
1084 fsflags |= MNT_NOSUID | MNT_USER;
1087 /* Load KLDs before we lock the covered vnode to avoid reversals. */
1089 if ((fsflags & MNT_UPDATE) == 0) {
1090 /* Don't try to load KLDs if we're mounting the root. */
1091 if (fsflags & MNT_ROOTFS)
1092 vfsp = vfs_byname(fstype);
1094 vfsp = vfs_byname_kld(fstype, td, &error);
1097 if (jailed(td->td_ucred) && !(vfsp->vfc_flags & VFCF_JAIL))
1102 * Get vnode to be covered or mount point's vnode in case of MNT_UPDATE.
1104 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1,
1105 UIO_SYSSPACE, fspath, td);
1109 NDFREE(&nd, NDF_ONLY_PNBUF);
1111 if ((fsflags & MNT_UPDATE) == 0) {
1112 pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK);
1113 strcpy(pathbuf, fspath);
1114 error = vn_path_to_global_path(td, vp, pathbuf, MNAMELEN);
1115 /* debug.disablefullpath == 1 results in ENODEV */
1116 if (error == 0 || error == ENODEV) {
1117 error = vfs_domount_first(td, vfsp, pathbuf, vp,
1120 free(pathbuf, M_TEMP);
1122 error = vfs_domount_update(td, vp, fsflags, optlist);
1128 * Unmount a filesystem.
1130 * Note: unmount takes a path to the vnode mounted on as argument, not
1131 * special file (as before).
1133 #ifndef _SYS_SYSPROTO_H_
1134 struct unmount_args {
1141 sys_unmount(struct thread *td, struct unmount_args *uap)
1143 struct nameidata nd;
1146 int error, id0, id1;
1148 AUDIT_ARG_VALUE(uap->flags);
1149 if (jailed(td->td_ucred) || usermount == 0) {
1150 error = priv_check(td, PRIV_VFS_UNMOUNT);
1155 pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK);
1156 error = copyinstr(uap->path, pathbuf, MNAMELEN, NULL);
1158 free(pathbuf, M_TEMP);
1161 if (uap->flags & MNT_BYFSID) {
1162 AUDIT_ARG_TEXT(pathbuf);
1163 /* Decode the filesystem ID. */
1164 if (sscanf(pathbuf, "FSID:%d:%d", &id0, &id1) != 2) {
1165 free(pathbuf, M_TEMP);
1169 mtx_lock(&mountlist_mtx);
1170 TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
1171 if (mp->mnt_stat.f_fsid.val[0] == id0 &&
1172 mp->mnt_stat.f_fsid.val[1] == id1) {
1177 mtx_unlock(&mountlist_mtx);
1180 * Try to find global path for path argument.
1182 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1,
1183 UIO_SYSSPACE, pathbuf, td);
1184 if (namei(&nd) == 0) {
1185 NDFREE(&nd, NDF_ONLY_PNBUF);
1186 error = vn_path_to_global_path(td, nd.ni_vp, pathbuf,
1188 if (error == 0 || error == ENODEV)
1191 mtx_lock(&mountlist_mtx);
1192 TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
1193 if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0) {
1198 mtx_unlock(&mountlist_mtx);
1200 free(pathbuf, M_TEMP);
1203 * Previously we returned ENOENT for a nonexistent path and
1204 * EINVAL for a non-mountpoint. We cannot tell these apart
1205 * now, so in the !MNT_BYFSID case return the more likely
1206 * EINVAL for compatibility.
1208 return ((uap->flags & MNT_BYFSID) ? ENOENT : EINVAL);
1212 * Don't allow unmounting the root filesystem.
1214 if (mp->mnt_flag & MNT_ROOTFS) {
1218 error = dounmount(mp, uap->flags, td);
1223 * Return error if any of the vnodes, ignoring the root vnode
1224 * and the syncer vnode, have non-zero usecount.
1226 * This function is purely advisory - it can return false positives
1230 vfs_check_usecounts(struct mount *mp)
1232 struct vnode *vp, *mvp;
1234 MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
1235 if ((vp->v_vflag & VV_ROOT) == 0 && vp->v_type != VNON &&
1236 vp->v_usecount != 0) {
1238 MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
1248 dounmount_cleanup(struct mount *mp, struct vnode *coveredvp, int mntkflags)
1251 mtx_assert(MNT_MTX(mp), MA_OWNED);
1252 mp->mnt_kern_flag &= ~mntkflags;
1253 if ((mp->mnt_kern_flag & MNTK_MWAIT) != 0) {
1254 mp->mnt_kern_flag &= ~MNTK_MWAIT;
1258 if (coveredvp != NULL) {
1259 VOP_UNLOCK(coveredvp, 0);
1262 vn_finished_write(mp);
1266 * Do the actual filesystem unmount.
1269 dounmount(struct mount *mp, int flags, struct thread *td)
1271 struct vnode *coveredvp;
1273 uint64_t async_flag;
1276 if ((coveredvp = mp->mnt_vnodecovered) != NULL) {
1277 mnt_gen_r = mp->mnt_gen;
1280 vn_lock(coveredvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_RETRY);
1282 * Check for mp being unmounted while waiting for the
1283 * covered vnode lock.
1285 if (coveredvp->v_mountedhere != mp ||
1286 coveredvp->v_mountedhere->mnt_gen != mnt_gen_r) {
1287 VOP_UNLOCK(coveredvp, 0);
1295 * Only privileged root, or (if MNT_USER is set) the user that did the
1296 * original mount is permitted to unmount this filesystem.
1298 error = vfs_suser(mp, td);
1300 if (coveredvp != NULL) {
1301 VOP_UNLOCK(coveredvp, 0);
1308 vn_start_write(NULL, &mp, V_WAIT | V_MNTREF);
1310 if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 ||
1311 (mp->mnt_flag & MNT_UPDATE) != 0 ||
1312 !TAILQ_EMPTY(&mp->mnt_uppers)) {
1313 dounmount_cleanup(mp, coveredvp, 0);
1316 mp->mnt_kern_flag |= MNTK_UNMOUNT | MNTK_NOINSMNTQ;
1317 if (flags & MNT_NONBUSY) {
1319 error = vfs_check_usecounts(mp);
1322 dounmount_cleanup(mp, coveredvp, MNTK_UNMOUNT |
1327 /* Allow filesystems to detect that a forced unmount is in progress. */
1328 if (flags & MNT_FORCE) {
1329 mp->mnt_kern_flag |= MNTK_UNMOUNTF;
1332 * Must be done after setting MNTK_UNMOUNTF and before
1333 * waiting for mnt_lockref to become 0.
1339 if (mp->mnt_lockref) {
1340 mp->mnt_kern_flag |= MNTK_DRAINING;
1341 error = msleep(&mp->mnt_lockref, MNT_MTX(mp), PVFS,
1345 KASSERT(mp->mnt_lockref == 0,
1346 ("%s: invalid lock refcount in the drain path @ %s:%d",
1347 __func__, __FILE__, __LINE__));
1349 ("%s: invalid return value for msleep in the drain path @ %s:%d",
1350 __func__, __FILE__, __LINE__));
1352 if (mp->mnt_flag & MNT_EXPUBLIC)
1353 vfs_setpublicfs(NULL, NULL, NULL);
1356 * From now, we can claim that the use reference on the
1357 * coveredvp is ours, and the ref can be released only by
1358 * successfull unmount by us, or left for later unmount
1359 * attempt. The previously acquired hold reference is no
1360 * longer needed to protect the vnode from reuse.
1362 if (coveredvp != NULL)
1365 vfs_msync(mp, MNT_WAIT);
1367 async_flag = mp->mnt_flag & MNT_ASYNC;
1368 mp->mnt_flag &= ~MNT_ASYNC;
1369 mp->mnt_kern_flag &= ~MNTK_ASYNC;
1371 cache_purgevfs(mp, false); /* remove cache entries for this file sys */
1372 vfs_deallocate_syncvnode(mp);
1373 if ((mp->mnt_flag & MNT_RDONLY) != 0 || (flags & MNT_FORCE) != 0 ||
1374 (error = VFS_SYNC(mp, MNT_WAIT)) == 0)
1375 error = VFS_UNMOUNT(mp, flags);
1376 vn_finished_write(mp);
1378 * If we failed to flush the dirty blocks for this mount point,
1379 * undo all the cdir/rdir and rootvnode changes we made above.
1380 * Unless we failed to do so because the device is reporting that
1381 * it doesn't exist anymore.
1383 if (error && error != ENXIO) {
1385 mp->mnt_kern_flag &= ~MNTK_NOINSMNTQ;
1386 if ((mp->mnt_flag & MNT_RDONLY) == 0) {
1388 vfs_allocate_syncvnode(mp);
1391 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF);
1392 mp->mnt_flag |= async_flag;
1393 if ((mp->mnt_flag & MNT_ASYNC) != 0 &&
1394 (mp->mnt_kern_flag & MNTK_NOASYNC) == 0)
1395 mp->mnt_kern_flag |= MNTK_ASYNC;
1396 if (mp->mnt_kern_flag & MNTK_MWAIT) {
1397 mp->mnt_kern_flag &= ~MNTK_MWAIT;
1402 VOP_UNLOCK(coveredvp, 0);
1405 mtx_lock(&mountlist_mtx);
1406 TAILQ_REMOVE(&mountlist, mp, mnt_list);
1407 mtx_unlock(&mountlist_mtx);
1408 EVENTHANDLER_DIRECT_INVOKE(vfs_unmounted, mp, td);
1409 if (coveredvp != NULL) {
1410 coveredvp->v_mountedhere = NULL;
1411 VOP_UNLOCK(coveredvp, 0);
1413 vfs_event_signal(NULL, VQ_UNMOUNT, 0);
1414 if (rootvnode != NULL && mp == rootvnode->v_mount) {
1418 if (mp == rootdevmp)
1420 vfs_mount_destroy(mp);
1425 * Report errors during filesystem mounting.
1428 vfs_mount_error(struct mount *mp, const char *fmt, ...)
1430 struct vfsoptlist *moptlist = mp->mnt_optnew;
1435 error = vfs_getopt(moptlist, "errmsg", (void **)&errmsg, &len);
1436 if (error || errmsg == NULL || len <= 0)
1440 vsnprintf(errmsg, (size_t)len, fmt, ap);
1445 vfs_opterror(struct vfsoptlist *opts, const char *fmt, ...)
1451 error = vfs_getopt(opts, "errmsg", (void **)&errmsg, &len);
1452 if (error || errmsg == NULL || len <= 0)
1456 vsnprintf(errmsg, (size_t)len, fmt, ap);
1461 * ---------------------------------------------------------------------
1462 * Functions for querying mount options/arguments from filesystems.
1466 * Check that no unknown options are given
1469 vfs_filteropt(struct vfsoptlist *opts, const char **legal)
1473 const char **t, *p, *q;
1476 TAILQ_FOREACH(opt, opts, link) {
1479 if (p[0] == 'n' && p[1] == 'o')
1481 for(t = global_opts; *t != NULL; t++) {
1482 if (strcmp(*t, p) == 0)
1485 if (strcmp(*t, q) == 0)
1491 for(t = legal; *t != NULL; t++) {
1492 if (strcmp(*t, p) == 0)
1495 if (strcmp(*t, q) == 0)
1501 snprintf(errmsg, sizeof(errmsg),
1502 "mount option <%s> is unknown", p);
1506 TAILQ_FOREACH(opt, opts, link) {
1507 if (strcmp(opt->name, "errmsg") == 0) {
1508 strncpy((char *)opt->value, errmsg, opt->len);
1513 printf("%s\n", errmsg);
1519 * Get a mount option by its name.
1521 * Return 0 if the option was found, ENOENT otherwise.
1522 * If len is non-NULL it will be filled with the length
1523 * of the option. If buf is non-NULL, it will be filled
1524 * with the address of the option.
1527 vfs_getopt(struct vfsoptlist *opts, const char *name, void **buf, int *len)
1531 KASSERT(opts != NULL, ("vfs_getopt: caller passed 'opts' as NULL"));
1533 TAILQ_FOREACH(opt, opts, link) {
1534 if (strcmp(name, opt->name) == 0) {
1547 vfs_getopt_pos(struct vfsoptlist *opts, const char *name)
1554 TAILQ_FOREACH(opt, opts, link) {
1555 if (strcmp(name, opt->name) == 0) {
1564 vfs_getopt_size(struct vfsoptlist *opts, const char *name, off_t *value)
1566 char *opt_value, *vtp;
1570 error = vfs_getopt(opts, name, (void **)&opt_value, &opt_len);
1573 if (opt_len == 0 || opt_value == NULL)
1575 if (opt_value[0] == '\0' || opt_value[opt_len - 1] != '\0')
1577 iv = strtoq(opt_value, &vtp, 0);
1578 if (vtp == opt_value || (vtp[0] != '\0' && vtp[1] != '\0'))
1606 vfs_getopts(struct vfsoptlist *opts, const char *name, int *error)
1611 TAILQ_FOREACH(opt, opts, link) {
1612 if (strcmp(name, opt->name) != 0)
1615 if (opt->len == 0 ||
1616 ((char *)opt->value)[opt->len - 1] != '\0') {
1620 return (opt->value);
1627 vfs_flagopt(struct vfsoptlist *opts, const char *name, uint64_t *w,
1632 TAILQ_FOREACH(opt, opts, link) {
1633 if (strcmp(name, opt->name) == 0) {
1646 vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...)
1652 KASSERT(opts != NULL, ("vfs_getopt: caller passed 'opts' as NULL"));
1654 TAILQ_FOREACH(opt, opts, link) {
1655 if (strcmp(name, opt->name) != 0)
1658 if (opt->len == 0 || opt->value == NULL)
1660 if (((char *)opt->value)[opt->len - 1] != '\0')
1663 ret = vsscanf(opt->value, fmt, ap);
1671 vfs_setopt(struct vfsoptlist *opts, const char *name, void *value, int len)
1675 TAILQ_FOREACH(opt, opts, link) {
1676 if (strcmp(name, opt->name) != 0)
1679 if (opt->value == NULL)
1682 if (opt->len != len)
1684 bcopy(value, opt->value, len);
1692 vfs_setopt_part(struct vfsoptlist *opts, const char *name, void *value, int len)
1696 TAILQ_FOREACH(opt, opts, link) {
1697 if (strcmp(name, opt->name) != 0)
1700 if (opt->value == NULL)
1706 bcopy(value, opt->value, len);
1714 vfs_setopts(struct vfsoptlist *opts, const char *name, const char *value)
1718 TAILQ_FOREACH(opt, opts, link) {
1719 if (strcmp(name, opt->name) != 0)
1722 if (opt->value == NULL)
1723 opt->len = strlen(value) + 1;
1724 else if (strlcpy(opt->value, value, opt->len) >= opt->len)
1732 * Find and copy a mount option.
1734 * The size of the buffer has to be specified
1735 * in len, if it is not the same length as the
1736 * mount option, EINVAL is returned.
1737 * Returns ENOENT if the option is not found.
1740 vfs_copyopt(struct vfsoptlist *opts, const char *name, void *dest, int len)
1744 KASSERT(opts != NULL, ("vfs_copyopt: caller passed 'opts' as NULL"));
1746 TAILQ_FOREACH(opt, opts, link) {
1747 if (strcmp(name, opt->name) == 0) {
1749 if (len != opt->len)
1751 bcopy(opt->value, dest, opt->len);
1759 __vfs_statfs(struct mount *mp, struct statfs *sbp)
1763 error = mp->mnt_op->vfs_statfs(mp, &mp->mnt_stat);
1764 if (sbp != &mp->mnt_stat)
1765 *sbp = mp->mnt_stat;
1770 vfs_mountedfrom(struct mount *mp, const char *from)
1773 bzero(mp->mnt_stat.f_mntfromname, sizeof mp->mnt_stat.f_mntfromname);
1774 strlcpy(mp->mnt_stat.f_mntfromname, from,
1775 sizeof mp->mnt_stat.f_mntfromname);
1779 * ---------------------------------------------------------------------
1780 * This is the api for building mount args and mounting filesystems from
1781 * inside the kernel.
1783 * The API works by accumulation of individual args. First error is
1786 * XXX: should be documented in new manpage kernel_mount(9)
1789 /* A memory allocation which must be freed when we are done */
1791 SLIST_ENTRY(mntaarg) next;
1794 /* The header for the mount arguments */
1799 SLIST_HEAD(, mntaarg) list;
1803 * Add a boolean argument.
1805 * flag is the boolean value.
1806 * name must start with "no".
1809 mount_argb(struct mntarg *ma, int flag, const char *name)
1812 KASSERT(name[0] == 'n' && name[1] == 'o',
1813 ("mount_argb(...,%s): name must start with 'no'", name));
1815 return (mount_arg(ma, name + (flag ? 2 : 0), NULL, 0));
1819 * Add an argument printf style
1822 mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...)
1825 struct mntaarg *maa;
1830 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO);
1831 SLIST_INIT(&ma->list);
1836 ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2),
1838 ma->v[ma->len].iov_base = (void *)(uintptr_t)name;
1839 ma->v[ma->len].iov_len = strlen(name) + 1;
1842 sb = sbuf_new_auto();
1844 sbuf_vprintf(sb, fmt, ap);
1847 len = sbuf_len(sb) + 1;
1848 maa = malloc(sizeof *maa + len, M_MOUNT, M_WAITOK | M_ZERO);
1849 SLIST_INSERT_HEAD(&ma->list, maa, next);
1850 bcopy(sbuf_data(sb), maa + 1, len);
1853 ma->v[ma->len].iov_base = maa + 1;
1854 ma->v[ma->len].iov_len = len;
1861 * Add an argument which is a userland string.
1864 mount_argsu(struct mntarg *ma, const char *name, const void *val, int len)
1866 struct mntaarg *maa;
1872 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO);
1873 SLIST_INIT(&ma->list);
1877 maa = malloc(sizeof *maa + len, M_MOUNT, M_WAITOK | M_ZERO);
1878 SLIST_INSERT_HEAD(&ma->list, maa, next);
1879 tbuf = (void *)(maa + 1);
1880 ma->error = copyinstr(val, tbuf, len, NULL);
1881 return (mount_arg(ma, name, tbuf, -1));
1887 * If length is -1, treat value as a C string.
1890 mount_arg(struct mntarg *ma, const char *name, const void *val, int len)
1894 ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO);
1895 SLIST_INIT(&ma->list);
1900 ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2),
1902 ma->v[ma->len].iov_base = (void *)(uintptr_t)name;
1903 ma->v[ma->len].iov_len = strlen(name) + 1;
1906 ma->v[ma->len].iov_base = (void *)(uintptr_t)val;
1908 ma->v[ma->len].iov_len = strlen(val) + 1;
1910 ma->v[ma->len].iov_len = len;
1916 * Free a mntarg structure
1919 free_mntarg(struct mntarg *ma)
1921 struct mntaarg *maa;
1923 while (!SLIST_EMPTY(&ma->list)) {
1924 maa = SLIST_FIRST(&ma->list);
1925 SLIST_REMOVE_HEAD(&ma->list, next);
1928 free(ma->v, M_MOUNT);
1933 * Mount a filesystem
1936 kernel_mount(struct mntarg *ma, uint64_t flags)
1941 KASSERT(ma != NULL, ("kernel_mount NULL ma"));
1942 KASSERT(ma->v != NULL, ("kernel_mount NULL ma->v"));
1943 KASSERT(!(ma->len & 1), ("kernel_mount odd ma->len (%d)", ma->len));
1945 auio.uio_iov = ma->v;
1946 auio.uio_iovcnt = ma->len;
1947 auio.uio_segflg = UIO_SYSSPACE;
1951 error = vfs_donmount(curthread, flags, &auio);
1957 * A printflike function to mount a filesystem.
1960 kernel_vmount(int flags, ...)
1962 struct mntarg *ma = NULL;
1968 va_start(ap, flags);
1970 cp = va_arg(ap, const char *);
1973 vp = va_arg(ap, const void *);
1974 ma = mount_arg(ma, cp, vp, (vp != NULL ? -1 : 0));
1978 error = kernel_mount(ma, flags);
1983 vfs_oexport_conv(const struct oexport_args *oexp, struct export_args *exp)
1986 bcopy(oexp, exp, sizeof(*oexp));
1987 exp->ex_numsecflavors = 0;