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