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