The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/vfs_mount.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1989, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  * (c) UNIX System Laboratories, Inc.
    5  * All or some portions of this file are derived from material licensed
    6  * to the University of California by American Telephone and Telegraph
    7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
    8  * the permission of UNIX System Laboratories, Inc.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the University of
   21  *      California, Berkeley and its contributors.
   22  * 4. Neither the name of the University nor the names of its contributors
   23  *    may be used to endorse or promote products derived from this software
   24  *    without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36  * SUCH DAMAGE.
   37  *
   38  * Copyright (c) 1999 Michael Smith
   39  * All rights reserved.
   40  * Copyright (c) 1999 Poul-Henning Kamp
   41  * All rights reserved.
   42  *
   43  * Redistribution and use in source and binary forms, with or without
   44  * modification, are permitted provided that the following conditions
   45  * are met:
   46  * 1. Redistributions of source code must retain the above copyright
   47  *    notice, this list of conditions and the following disclaimer.
   48  * 2. Redistributions in binary form must reproduce the above copyright
   49  *    notice, this list of conditions and the following disclaimer in the
   50  *    documentation and/or other materials provided with the distribution.
   51  * 
   52  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   62  * SUCH DAMAGE.
   63  *
   64  * $FreeBSD: releng/5.0/sys/kern/vfs_mount.c 108086 2002-12-19 09:40:13Z alfred $
   65  */
   66 
   67 #include <sys/param.h>
   68 #include <sys/conf.h>
   69 #include <sys/cons.h>
   70 #include <sys/kernel.h>
   71 #include <sys/linker.h>
   72 #include <sys/mac.h>
   73 #include <sys/malloc.h>
   74 #include <sys/mount.h>
   75 #include <sys/mutex.h>
   76 #include <sys/namei.h>
   77 #include <sys/proc.h>
   78 #include <sys/reboot.h>
   79 #include <sys/sysproto.h>
   80 #include <sys/sx.h>
   81 #include <sys/sysctl.h>
   82 #include <sys/sysent.h>
   83 #include <sys/systm.h>
   84 #include <sys/vnode.h>
   85 
   86 #include <geom/geom.h>
   87 
   88 #include <machine/stdarg.h>
   89 
   90 #include "opt_rootdevname.h"
   91 #include "opt_ddb.h"
   92 #include "opt_mac.h"
   93 
   94 #ifdef DDB
   95 #include <ddb/ddb.h>
   96 #endif
   97 
   98 #define ROOTNAME        "root_device"
   99 
  100 static void     checkdirs(struct vnode *olddp, struct vnode *newdp);
  101 static int      vfs_nmount(struct thread *td, int, struct uio *);
  102 static int      vfs_mountroot_try(char *mountfrom);
  103 static int      vfs_mountroot_ask(void);
  104 static void     gets(char *cp);
  105 
  106 static int      usermount = 0;  /* if 1, non-root can mount fs. */
  107 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, "");
  108 
  109 MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure");
  110 
  111 /* List of mounted filesystems. */
  112 struct mntlist mountlist = TAILQ_HEAD_INITIALIZER(mountlist);
  113 
  114 /* For any iteration/modification of mountlist */
  115 struct mtx mountlist_mtx;
  116 
  117 /* For any iteration/modification of mnt_vnodelist */
  118 struct mtx mntvnode_mtx;
  119 
  120 /*
  121  * The vnode of the system's root (/ in the filesystem, without chroot
  122  * active.)
  123  */
  124 struct vnode    *rootvnode;
  125 
  126 /*
  127  * The root filesystem is detailed in the kernel environment variable
  128  * vfs.root.mountfrom, which is expected to be in the general format
  129  *
  130  * <vfsname>:[<path>]
  131  * vfsname   := the name of a VFS known to the kernel and capable
  132  *              of being mounted as root
  133  * path      := disk device name or other data used by the filesystem
  134  *              to locate its physical store
  135  */
  136 
  137 /* 
  138  * The root specifiers we will try if RB_CDROM is specified.
  139  */
  140 static char *cdrom_rootdevnames[] = {
  141         "cd9660:cd0a",
  142         "cd9660:acd0a",
  143         "cd9660:wcd0a",
  144         NULL
  145 };
  146 
  147 /* legacy find-root code */
  148 char            *rootdevnames[2] = {NULL, NULL};
  149 static int      setrootbyname(char *name);
  150 dev_t           rootdev = NODEV;
  151 
  152 /* Remove one mount option. */
  153 static void
  154 vfs_freeopt(struct vfsoptlist *opts, struct vfsopt *opt)
  155 {
  156 
  157         TAILQ_REMOVE(opts, opt, link);
  158         free(opt->name, M_MOUNT);
  159         if (opt->value != NULL)
  160                 free(opt->value, M_MOUNT);
  161 #ifdef INVARIANTS
  162         else if (opt->len != 0)
  163                 panic("%s: mount option with NULL value but length != 0",
  164                     __func__);
  165 #endif
  166         free(opt, M_MOUNT);
  167 }
  168 
  169 /* Release all resources related to the mount options. */
  170 static void
  171 vfs_freeopts(struct vfsoptlist *opts)
  172 {
  173         struct vfsopt *opt;
  174 
  175         while (!TAILQ_EMPTY(opts)) {
  176                 opt = TAILQ_FIRST(opts);
  177                 vfs_freeopt(opts, opt);
  178         }
  179         free(opts, M_MOUNT);
  180 }
  181 
  182 /*
  183  * If a mount option is specified several times,
  184  * (with or without the "no" prefix) only keep
  185  * the last occurence of it.
  186  */
  187 static void
  188 vfs_sanitizeopts(struct vfsoptlist *opts)
  189 {
  190         struct vfsopt *opt, *opt2, *tmp;
  191         int noopt;
  192 
  193         TAILQ_FOREACH_REVERSE(opt, opts, vfsoptlist, link) {
  194                 if (strncmp(opt->name, "no", 2) == 0)
  195                         noopt = 1;
  196                 else
  197                         noopt = 0;
  198                 opt2 = TAILQ_PREV(opt, vfsoptlist, link);
  199                 while (opt2 != NULL) {
  200                         if (strcmp(opt2->name, opt->name) == 0 ||
  201                             (noopt && strcmp(opt->name + 2, opt2->name) == 0) ||
  202                             (!noopt && strncmp(opt2->name, "no", 2) == 0 &&
  203                             strcmp(opt2->name + 2, opt->name) == 0)) {
  204                                 tmp = TAILQ_PREV(opt2, vfsoptlist, link);
  205                                 vfs_freeopt(opts, opt2);
  206                                 opt2 = tmp;
  207                         } else {
  208                                 opt2 = TAILQ_PREV(opt2, vfsoptlist, link);
  209                         }
  210                 }
  211         }
  212 }
  213 
  214 /*
  215  * Build a linked list of mount options from a struct uio.
  216  */
  217 static int
  218 vfs_buildopts(struct uio *auio, struct vfsoptlist **options)
  219 {
  220         struct vfsoptlist *opts;
  221         struct vfsopt *opt;
  222         unsigned int i, iovcnt;
  223         int error, namelen, optlen;
  224 
  225         iovcnt = auio->uio_iovcnt;
  226         opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK);
  227         TAILQ_INIT(opts);
  228         for (i = 0; i < iovcnt; i += 2) {
  229                 opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK);
  230                 namelen = auio->uio_iov[i].iov_len;
  231                 optlen = auio->uio_iov[i + 1].iov_len;
  232                 opt->name = malloc(namelen, M_MOUNT, M_WAITOK);
  233                 opt->value = NULL;
  234                 if (auio->uio_segflg == UIO_SYSSPACE) {
  235                         bcopy(auio->uio_iov[i].iov_base, opt->name, namelen);
  236                 } else {
  237                         error = copyin(auio->uio_iov[i].iov_base, opt->name,
  238                             namelen);
  239                         if (error)
  240                                 goto bad;
  241                 }
  242                 opt->len = optlen;
  243                 if (optlen != 0) {
  244                         opt->value = malloc(optlen, M_MOUNT, M_WAITOK);
  245                         if (auio->uio_segflg == UIO_SYSSPACE) {
  246                                 bcopy(auio->uio_iov[i + 1].iov_base, opt->value,
  247                                     optlen);
  248                         } else {
  249                                 error = copyin(auio->uio_iov[i + 1].iov_base,
  250                                     opt->value, optlen);
  251                                 if (error)
  252                                         goto bad;
  253                         }
  254                 }
  255                 TAILQ_INSERT_TAIL(opts, opt, link);
  256         }
  257         vfs_sanitizeopts(opts);
  258         *options = opts;
  259         return (0);
  260 bad:
  261         vfs_freeopts(opts);
  262         return (error);
  263 }
  264 
  265 /*
  266  * Merge the old mount options with the new ones passed
  267  * in the MNT_UPDATE case.
  268  */
  269 static void
  270 vfs_mergeopts(struct vfsoptlist *toopts, struct vfsoptlist *opts)
  271 {
  272         struct vfsopt *opt, *opt2, *new;
  273 
  274         TAILQ_FOREACH(opt, opts, link) {
  275                 /*
  276                  * Check that this option hasn't been redefined
  277                  * nor cancelled with a "no" mount option.
  278                  */
  279                 opt2 = TAILQ_FIRST(toopts);
  280                 while (opt2 != NULL) {
  281                         if (strcmp(opt2->name, opt->name) == 0)
  282                                 goto next;
  283                         if (strncmp(opt2->name, "no", 2) == 0 &&
  284                             strcmp(opt2->name + 2, opt->name) == 0) {
  285                                 vfs_freeopt(toopts, opt2);
  286                                 goto next;
  287                         }
  288                         opt2 = TAILQ_NEXT(opt2, link);
  289                 }
  290                 /* We want this option, duplicate it. */
  291                 new = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK);
  292                 new->name = malloc(strlen(opt->name) + 1, M_MOUNT, M_WAITOK);
  293                 strcpy(new->name, opt->name);
  294                 if (opt->len != 0) {
  295                         new->value = malloc(opt->len, M_MOUNT, M_WAITOK);
  296                         bcopy(opt->value, new->value, opt->len);
  297                 } else {
  298                         new->value = NULL;
  299                 }
  300                 new->len = opt->len;
  301                 TAILQ_INSERT_TAIL(toopts, new, link);
  302 next:
  303                 continue;
  304         }
  305 }
  306 
  307 /*
  308  * New mount API.
  309  */
  310 int
  311 nmount(td, uap)
  312         struct thread *td;
  313         struct nmount_args /* {
  314                 struct iovec *iovp;
  315                 unsigned int iovcnt;
  316                 int flags;
  317         } */ *uap;
  318 {
  319         struct uio auio;
  320         struct iovec *iov, *needfree;
  321         struct iovec aiov[UIO_SMALLIOV];
  322         unsigned int i;
  323         int error;
  324         u_int iovlen, iovcnt;
  325 
  326         iovcnt = uap->iovcnt;
  327         iovlen = iovcnt * sizeof (struct iovec);
  328         /*
  329          * Check that we have an even number of iovec's
  330          * and that we have at least two options.
  331          */
  332         if ((iovcnt & 1) || (iovcnt < 4) || (iovcnt > UIO_MAXIOV))
  333                 return (EINVAL);
  334 
  335         if (iovcnt > UIO_SMALLIOV) {
  336                 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
  337                 needfree = iov;
  338         } else {
  339                 iov = aiov;
  340                 needfree = NULL;
  341         }
  342         auio.uio_iov = iov;
  343         auio.uio_iovcnt = iovcnt;
  344         auio.uio_segflg = UIO_USERSPACE;
  345         if ((error = copyin(uap->iovp, iov, iovlen)))
  346                 goto finish;
  347 
  348         for (i = 0; i < iovcnt; i++) {
  349                 if (iov->iov_len > MMAXOPTIONLEN) {
  350                         error = EINVAL;
  351                         goto finish;
  352                 }
  353                 iov++;
  354         }
  355         error = vfs_nmount(td, uap->flags, &auio);
  356 finish:
  357         if (needfree != NULL)
  358                 free(needfree, M_TEMP);
  359         return (error);
  360 }
  361 
  362 int
  363 kernel_mount(iovp, iovcnt, flags)
  364         struct iovec *iovp;
  365         unsigned int iovcnt;
  366         int flags;
  367 {
  368         struct uio auio;
  369         int error;
  370 
  371         /*
  372          * Check that we have an even number of iovec's
  373          * and that we have at least two options.
  374          */
  375         if ((iovcnt & 1) || (iovcnt < 4))
  376                 return (EINVAL);
  377 
  378         auio.uio_iov = iovp;
  379         auio.uio_iovcnt = iovcnt;
  380         auio.uio_segflg = UIO_SYSSPACE;
  381 
  382         error = vfs_nmount(curthread, flags, &auio);
  383         return (error);
  384 }
  385 
  386 int
  387 kernel_vmount(int flags, ...)
  388 {
  389         struct iovec *iovp;
  390         struct uio auio;
  391         va_list ap;
  392         unsigned int iovcnt, iovlen, len;
  393         const char *cp;
  394         char *buf, *pos;
  395         size_t n;
  396         int error, i;
  397 
  398         len = 0;
  399         va_start(ap, flags);
  400         for (iovcnt = 0; (cp = va_arg(ap, const char *)) != NULL; iovcnt++)
  401                 len += strlen(cp) + 1;
  402         va_end(ap);
  403 
  404         if (iovcnt < 4 || iovcnt & 1)
  405                 return (EINVAL);
  406 
  407         iovlen = iovcnt * sizeof (struct iovec);
  408         MALLOC(iovp, struct iovec *, iovlen, M_MOUNT, M_WAITOK);
  409         MALLOC(buf, char *, len, M_MOUNT, M_WAITOK);
  410         pos = buf;
  411         va_start(ap, flags);
  412         for (i = 0; i < iovcnt; i++) {
  413                 cp = va_arg(ap, const char *);
  414                 copystr(cp, pos, len - (pos - buf), &n);
  415                 iovp[i].iov_base = pos;
  416                 iovp[i].iov_len = n;
  417                 pos += n;
  418         }
  419         va_end(ap);
  420 
  421         auio.uio_iov = iovp;
  422         auio.uio_iovcnt = iovcnt;
  423         auio.uio_segflg = UIO_SYSSPACE;
  424 
  425         error = vfs_nmount(curthread, flags, &auio);
  426         FREE(iovp, M_MOUNT);
  427         FREE(buf, M_MOUNT);
  428         return (error);
  429 }
  430 
  431 /*
  432  * vfs_nmount(): actually attempt a filesystem mount.
  433  */
  434 static int
  435 vfs_nmount(td, fsflags, fsoptions)
  436         struct thread *td;
  437         int fsflags;            /* Flags common to all filesystems. */
  438         struct uio *fsoptions;  /* Options local to the filesystem. */
  439 {
  440         linker_file_t lf;
  441         struct vnode *vp;
  442         struct mount *mp;
  443         struct vfsconf *vfsp;
  444         struct vfsoptlist *optlist;
  445         char *fstype, *fspath;
  446         int error, flag = 0, kern_flag = 0;
  447         int fstypelen, fspathlen;
  448         struct vattr va;
  449         struct nameidata nd;
  450 
  451         error = vfs_buildopts(fsoptions, &optlist);
  452         if (error)
  453                 return (error);
  454 
  455         /*
  456          * We need these two options before the others,
  457          * and they are mandatory for any filesystem.
  458          * Ensure they are NUL terminated as well.
  459          */
  460         fstypelen = 0;
  461         error = vfs_getopt(optlist, "fstype", (void **)&fstype, &fstypelen);
  462         if (error || fstype[fstypelen - 1] != '\0') {
  463                 error = EINVAL;
  464                 goto bad;
  465         }
  466         fspathlen = 0;
  467         error = vfs_getopt(optlist, "fspath", (void **)&fspath, &fspathlen);
  468         if (error || fspath[fspathlen - 1] != '\0') {
  469                 error = EINVAL;
  470                 goto bad;
  471         }
  472 
  473         /*
  474          * Be ultra-paranoid about making sure the type and fspath
  475          * variables will fit in our mp buffers, including the
  476          * terminating NUL.
  477          */
  478         if (fstypelen >= MFSNAMELEN - 1 || fspathlen >= MNAMELEN - 1) {
  479                 error = ENAMETOOLONG;
  480                 goto bad;
  481         }
  482 
  483         if (usermount == 0) {
  484                 error = suser(td);
  485                 if (error)
  486                         goto bad;
  487         }
  488         /*
  489          * Do not allow NFS export by non-root users.
  490          */
  491         if (fsflags & MNT_EXPORTED) {
  492                 error = suser(td);
  493                 if (error)
  494                         goto bad;
  495         }
  496         /*
  497          * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users.
  498          */
  499         if (suser(td)) 
  500                 fsflags |= MNT_NOSUID | MNT_NODEV;
  501         /*
  502          * Get vnode to be covered
  503          */
  504         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, td);
  505         if ((error = namei(&nd)) != 0)
  506                 goto bad;
  507         NDFREE(&nd, NDF_ONLY_PNBUF);
  508         vp = nd.ni_vp;
  509         if (fsflags & MNT_UPDATE) {
  510                 if ((vp->v_vflag & VV_ROOT) == 0) {
  511                         vput(vp);
  512                         error = EINVAL;
  513                         goto bad;
  514                 }
  515                 mp = vp->v_mount;
  516                 flag = mp->mnt_flag;
  517                 kern_flag = mp->mnt_kern_flag;
  518                 /*
  519                  * We only allow the filesystem to be reloaded if it
  520                  * is currently mounted read-only.
  521                  */
  522                 if ((fsflags & MNT_RELOAD) &&
  523                     ((mp->mnt_flag & MNT_RDONLY) == 0)) {
  524                         vput(vp);
  525                         error = EOPNOTSUPP;     /* Needs translation */
  526                         goto bad;
  527                 }
  528                 /*
  529                  * Only root, or the user that did the original mount is
  530                  * permitted to update it.
  531                  */
  532                 if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) {
  533                         error = suser(td);
  534                         if (error) {
  535                                 vput(vp);
  536                                 goto bad;
  537                         }
  538                 }
  539                 if (vfs_busy(mp, LK_NOWAIT, 0, td)) {
  540                         vput(vp);
  541                         error = EBUSY;
  542                         goto bad;
  543                 }
  544                 VI_LOCK(vp);
  545                 if ((vp->v_iflag & VI_MOUNT) != 0 ||
  546                     vp->v_mountedhere != NULL) {
  547                         VI_UNLOCK(vp);
  548                         vfs_unbusy(mp, td);
  549                         vput(vp);
  550                         error = EBUSY;
  551                         goto bad;
  552                 }
  553                 vp->v_iflag |= VI_MOUNT;
  554                 VI_UNLOCK(vp);
  555                 mp->mnt_flag |= fsflags &
  556                     (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT);
  557                 VOP_UNLOCK(vp, 0, td);
  558                 mp->mnt_optnew = optlist;
  559                 vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt);
  560                 goto update;
  561         }
  562         /*
  563          * If the user is not root, ensure that they own the directory
  564          * onto which we are attempting to mount.
  565          */
  566         error = VOP_GETATTR(vp, &va, td->td_ucred, td);
  567         if (error) {
  568                 vput(vp);
  569                 goto bad;
  570         }
  571         if (va.va_uid != td->td_ucred->cr_uid) {
  572                 error = suser(td);
  573                 if (error) {
  574                         vput(vp);
  575                         goto bad;
  576                 }
  577         }
  578         if ((error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0)) != 0) {
  579                 vput(vp);
  580                 goto bad;
  581         }
  582         if (vp->v_type != VDIR) {
  583                 vput(vp);
  584                 error = ENOTDIR;
  585                 goto bad;
  586         }
  587         for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
  588                 if (!strcmp(vfsp->vfc_name, fstype))
  589                         break;
  590         if (vfsp == NULL) {
  591                 /* Only load modules for root (very important!). */
  592                 error = suser(td);
  593                 if (error) {
  594                         vput(vp);
  595                         goto bad;
  596                 }
  597                 error = securelevel_gt(td->td_ucred, 0);
  598                 if (error) {
  599                         vput(vp);
  600                         goto bad;
  601                 }
  602                 error = linker_load_module(NULL, fstype, NULL, NULL, &lf);
  603                 if (error || lf == NULL) {
  604                         vput(vp);
  605                         if (lf == NULL)
  606                                 error = ENODEV;
  607                         goto bad;
  608                 }
  609                 lf->userrefs++;
  610                 /* Look up again to see if the VFS was loaded. */
  611                 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
  612                         if (!strcmp(vfsp->vfc_name, fstype))
  613                                 break;
  614                 if (vfsp == NULL) {
  615                         lf->userrefs--;
  616                         linker_file_unload(lf);
  617                         vput(vp);
  618                         error = ENODEV;
  619                         goto bad;
  620                 }
  621         }
  622         VI_LOCK(vp);
  623         if ((vp->v_iflag & VI_MOUNT) != 0 ||
  624             vp->v_mountedhere != NULL) {
  625                 VI_UNLOCK(vp);
  626                 vput(vp);
  627                 error = EBUSY;
  628                 goto bad;
  629         }
  630         vp->v_iflag |= VI_MOUNT;
  631         VI_UNLOCK(vp);
  632 
  633         /*
  634          * Allocate and initialize the filesystem.
  635          */
  636         mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO);
  637         TAILQ_INIT(&mp->mnt_nvnodelist);
  638         TAILQ_INIT(&mp->mnt_reservedvnlist);
  639         lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE);
  640         (void)vfs_busy(mp, LK_NOWAIT, 0, td);
  641         mp->mnt_op = vfsp->vfc_vfsops;
  642         mp->mnt_vfc = vfsp;
  643         vfsp->vfc_refcount++;
  644         mp->mnt_stat.f_type = vfsp->vfc_typenum;
  645         mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
  646         strlcpy(mp->mnt_stat.f_fstypename, fstype, MFSNAMELEN);
  647         mp->mnt_vnodecovered = vp;
  648         mp->mnt_cred = crdup(td->td_ucred);
  649         mp->mnt_stat.f_owner = td->td_ucred->cr_uid;
  650         strlcpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN);
  651         mp->mnt_iosize_max = DFLTPHYS;
  652 #ifdef MAC
  653         mac_init_mount(mp);
  654         mac_create_mount(td->td_ucred, mp);
  655 #endif
  656         VOP_UNLOCK(vp, 0, td);
  657         mp->mnt_optnew = optlist;       /* XXXMAC: should this be above? */
  658 
  659 update:
  660         /*
  661          * Check if the fs implements the new VFS_NMOUNT()
  662          * function, since the new system call was used.
  663          */
  664         if (mp->mnt_op->vfs_mount != NULL) {
  665                 printf("%s doesn't support the new mount syscall\n",
  666                     mp->mnt_vfc->vfc_name);
  667                 VI_LOCK(vp);
  668                 vp->v_iflag &= ~VI_MOUNT;
  669                 VI_UNLOCK(vp);
  670                 if (mp->mnt_flag & MNT_UPDATE)
  671                         vfs_unbusy(mp, td);
  672                 else {
  673                         mp->mnt_vfc->vfc_refcount--;
  674                         vfs_unbusy(mp, td);
  675 #ifdef MAC
  676                         mac_destroy_mount(mp);
  677 #endif
  678                         free(mp, M_MOUNT);
  679                 }
  680                 vrele(vp);
  681                 error = EOPNOTSUPP;
  682                 goto bad;
  683         }
  684 
  685         /*
  686          * Set the mount level flags.
  687          */
  688         if (fsflags & MNT_RDONLY)
  689                 mp->mnt_flag |= MNT_RDONLY;
  690         else if (mp->mnt_flag & MNT_RDONLY)
  691                 mp->mnt_kern_flag |= MNTK_WANTRDWR;
  692         mp->mnt_flag &=~ MNT_UPDATEMASK;
  693         mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE);
  694         /*
  695          * Mount the filesystem.
  696          * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
  697          * get.  No freeing of cn_pnbuf.
  698          */
  699         error = VFS_NMOUNT(mp, &nd, td);
  700         if (!error) {
  701                 if (mp->mnt_opt != NULL)
  702                         vfs_freeopts(mp->mnt_opt);
  703                 mp->mnt_opt = mp->mnt_optnew;
  704         }
  705         /*
  706          * Prevent external consumers of mount
  707          * options to read mnt_optnew.
  708          */
  709         mp->mnt_optnew = NULL;
  710         if (mp->mnt_flag & MNT_UPDATE) {
  711                 if (mp->mnt_kern_flag & MNTK_WANTRDWR)
  712                         mp->mnt_flag &= ~MNT_RDONLY;
  713                 mp->mnt_flag &=~
  714                     (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_SNAPSHOT);
  715                 mp->mnt_kern_flag &=~ MNTK_WANTRDWR;
  716                 if (error) {
  717                         mp->mnt_flag = flag;
  718                         mp->mnt_kern_flag = kern_flag;
  719                 }
  720                 if ((mp->mnt_flag & MNT_RDONLY) == 0) {
  721                         if (mp->mnt_syncer == NULL)
  722                                 error = vfs_allocate_syncvnode(mp);
  723                 } else {
  724                         if (mp->mnt_syncer != NULL)
  725                                 vrele(mp->mnt_syncer);
  726                         mp->mnt_syncer = NULL;
  727                 }
  728                 vfs_unbusy(mp, td);
  729                 VI_LOCK(vp);
  730                 vp->v_iflag &= ~VI_MOUNT;
  731                 VI_UNLOCK(vp);
  732                 vrele(vp);
  733                 return (error);
  734         }
  735         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  736         /*
  737          * Put the new filesystem on the mount list after root.
  738          */
  739         cache_purge(vp);
  740         if (!error) {
  741                 struct vnode *newdp;
  742 
  743                 VI_LOCK(vp);
  744                 vp->v_iflag &= ~VI_MOUNT;
  745                 VI_UNLOCK(vp);
  746                 vp->v_mountedhere = mp;
  747                 mtx_lock(&mountlist_mtx);
  748                 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
  749                 mtx_unlock(&mountlist_mtx);
  750                 if (VFS_ROOT(mp, &newdp))
  751                         panic("mount: lost mount");
  752                 checkdirs(vp, newdp);
  753                 vput(newdp);
  754                 VOP_UNLOCK(vp, 0, td);
  755                 if ((mp->mnt_flag & MNT_RDONLY) == 0)
  756                         error = vfs_allocate_syncvnode(mp);
  757                 vfs_unbusy(mp, td);
  758                 if ((error = VFS_START(mp, 0, td)) != 0) {
  759                         vrele(vp);
  760                         goto bad;
  761                 }
  762         } else {
  763                 VI_LOCK(vp);
  764                 vp->v_iflag &= ~VI_MOUNT;
  765                 VI_UNLOCK(vp);
  766                 mp->mnt_vfc->vfc_refcount--;
  767                 vfs_unbusy(mp, td);
  768 #ifdef MAC
  769                 mac_destroy_mount(mp);
  770 #endif
  771                 free(mp, M_MOUNT);
  772                 vput(vp);
  773                 goto bad;
  774         }
  775         return (0);
  776 bad:
  777         vfs_freeopts(optlist);
  778         return (error);
  779 }
  780 
  781 /*
  782  * Old mount API.
  783  */
  784 #ifndef _SYS_SYSPROTO_H_
  785 struct mount_args {
  786         char    *type;
  787         char    *path;
  788         int     flags;
  789         caddr_t data;
  790 };
  791 #endif
  792 /* ARGSUSED */
  793 int
  794 mount(td, uap)
  795         struct thread *td;
  796         struct mount_args /* {
  797                 char *type;
  798                 char *path;
  799                 int flags;
  800                 caddr_t data;
  801         } */ *uap;
  802 {
  803         char *fstype;
  804         char *fspath;
  805         int error;
  806 
  807         fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK);
  808         fspath = malloc(MNAMELEN, M_TEMP, M_WAITOK);
  809 
  810         /*
  811          * vfs_mount() actually takes a kernel string for `type' and
  812          * `path' now, so extract them.
  813          */
  814         error = copyinstr(uap->type, fstype, MFSNAMELEN, NULL);
  815         if (error == 0)
  816                 error = copyinstr(uap->path, fspath, MNAMELEN, NULL);
  817         if (error == 0)
  818                 error = vfs_mount(td, fstype, fspath, uap->flags,
  819                     uap->data);
  820         free(fstype, M_TEMP);
  821         free(fspath, M_TEMP);
  822         return (error);
  823 }
  824 
  825 /*
  826  * vfs_mount(): actually attempt a filesystem mount.
  827  *
  828  * This routine is designed to be a "generic" entry point for routines
  829  * that wish to mount a filesystem. All parameters except `fsdata' are
  830  * pointers into kernel space. `fsdata' is currently still a pointer
  831  * into userspace.
  832  */
  833 int
  834 vfs_mount(td, fstype, fspath, fsflags, fsdata)
  835         struct thread *td;
  836         const char *fstype;
  837         char *fspath;
  838         int fsflags;
  839         void *fsdata;
  840 {
  841         linker_file_t lf;
  842         struct vnode *vp;
  843         struct mount *mp;
  844         struct vfsconf *vfsp;
  845         int error, flag = 0, kern_flag = 0;
  846         struct vattr va;
  847         struct nameidata nd;
  848 
  849         /*
  850          * Be ultra-paranoid about making sure the type and fspath
  851          * variables will fit in our mp buffers, including the
  852          * terminating NUL.
  853          */
  854         if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN)
  855                 return (ENAMETOOLONG);
  856 
  857         if (usermount == 0) {
  858                 error = suser(td);
  859                 if (error)
  860                         return (error);
  861         }
  862         /*
  863          * Do not allow NFS export by non-root users.
  864          */
  865         if (fsflags & MNT_EXPORTED) {
  866                 error = suser(td);
  867                 if (error)
  868                         return (error);
  869         }
  870         /*
  871          * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users.
  872          */
  873         if (suser(td)) 
  874                 fsflags |= MNT_NOSUID | MNT_NODEV;
  875         /*
  876          * Get vnode to be covered
  877          */
  878         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, td);
  879         if ((error = namei(&nd)) != 0)
  880                 return (error);
  881         NDFREE(&nd, NDF_ONLY_PNBUF);
  882         vp = nd.ni_vp;
  883         if (fsflags & MNT_UPDATE) {
  884                 if ((vp->v_vflag & VV_ROOT) == 0) {
  885                         vput(vp);
  886                         return (EINVAL);
  887                 }
  888                 mp = vp->v_mount;
  889                 flag = mp->mnt_flag;
  890                 kern_flag = mp->mnt_kern_flag;
  891                 /*
  892                  * We only allow the filesystem to be reloaded if it
  893                  * is currently mounted read-only.
  894                  */
  895                 if ((fsflags & MNT_RELOAD) &&
  896                     ((mp->mnt_flag & MNT_RDONLY) == 0)) {
  897                         vput(vp);
  898                         return (EOPNOTSUPP);    /* Needs translation */
  899                 }
  900                 /*
  901                  * Only root, or the user that did the original mount is
  902                  * permitted to update it.
  903                  */
  904                 if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) {
  905                         error = suser(td);
  906                         if (error) {
  907                                 vput(vp);
  908                                 return (error);
  909                         }
  910                 }
  911                 if (vfs_busy(mp, LK_NOWAIT, 0, td)) {
  912                         vput(vp);
  913                         return (EBUSY);
  914                 }
  915                 VI_LOCK(vp);
  916                 if ((vp->v_iflag & VI_MOUNT) != 0 ||
  917                     vp->v_mountedhere != NULL) {
  918                         VI_UNLOCK(vp);
  919                         vfs_unbusy(mp, td);
  920                         vput(vp);
  921                         return (EBUSY);
  922                 }
  923                 vp->v_iflag |= VI_MOUNT;
  924                 VI_UNLOCK(vp);
  925                 mp->mnt_flag |= fsflags &
  926                     (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT);
  927                 VOP_UNLOCK(vp, 0, td);
  928                 goto update;
  929         }
  930         /*
  931          * If the user is not root, ensure that they own the directory
  932          * onto which we are attempting to mount.
  933          */
  934         error = VOP_GETATTR(vp, &va, td->td_ucred, td);
  935         if (error) {
  936                 vput(vp);
  937                 return (error);
  938         }
  939         if (va.va_uid != td->td_ucred->cr_uid) {
  940                 error = suser(td);
  941                 if (error) {
  942                         vput(vp);
  943                         return (error);
  944                 }
  945         }
  946         if ((error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0)) != 0) {
  947                 vput(vp);
  948                 return (error);
  949         }
  950         if (vp->v_type != VDIR) {
  951                 vput(vp);
  952                 return (ENOTDIR);
  953         }
  954         for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
  955                 if (!strcmp(vfsp->vfc_name, fstype))
  956                         break;
  957         if (vfsp == NULL) {
  958                 /* Only load modules for root (very important!). */
  959                 error = suser(td);
  960                 if (error) {
  961                         vput(vp);
  962                         return (error);
  963                 }
  964                 error = securelevel_gt(td->td_ucred, 0);
  965                 if (error) {
  966                         vput(vp);
  967                         return (error);
  968                 }
  969                 error = linker_load_module(NULL, fstype, NULL, NULL, &lf);
  970                 if (error || lf == NULL) {
  971                         vput(vp);
  972                         if (lf == NULL)
  973                                 error = ENODEV;
  974                         return (error);
  975                 }
  976                 lf->userrefs++;
  977                 /* Look up again to see if the VFS was loaded. */
  978                 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
  979                         if (!strcmp(vfsp->vfc_name, fstype))
  980                                 break;
  981                 if (vfsp == NULL) {
  982                         lf->userrefs--;
  983                         linker_file_unload(lf);
  984                         vput(vp);
  985                         return (ENODEV);
  986                 }
  987         }
  988         VI_LOCK(vp);
  989         if ((vp->v_iflag & VI_MOUNT) != 0 ||
  990             vp->v_mountedhere != NULL) {
  991                 VI_UNLOCK(vp);
  992                 vput(vp);
  993                 return (EBUSY);
  994         }
  995         vp->v_iflag |= VI_MOUNT;
  996         VI_UNLOCK(vp);
  997 
  998         /*
  999          * Allocate and initialize the filesystem.
 1000          */
 1001         mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO);
 1002         TAILQ_INIT(&mp->mnt_nvnodelist);
 1003         TAILQ_INIT(&mp->mnt_reservedvnlist);
 1004         lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE);
 1005         (void)vfs_busy(mp, LK_NOWAIT, 0, td);
 1006         mp->mnt_op = vfsp->vfc_vfsops;
 1007         mp->mnt_vfc = vfsp;
 1008         vfsp->vfc_refcount++;
 1009         mp->mnt_stat.f_type = vfsp->vfc_typenum;
 1010         mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
 1011         strlcpy(mp->mnt_stat.f_fstypename, fstype, MFSNAMELEN);
 1012         mp->mnt_vnodecovered = vp;
 1013         mp->mnt_cred = crdup(td->td_ucred);
 1014         mp->mnt_stat.f_owner = td->td_ucred->cr_uid;
 1015         strlcpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN);
 1016         mp->mnt_iosize_max = DFLTPHYS;
 1017 #ifdef MAC
 1018         mac_init_mount(mp);
 1019         mac_create_mount(td->td_ucred, mp);
 1020 #endif
 1021         VOP_UNLOCK(vp, 0, td);
 1022 update:
 1023         /*
 1024          * Check if the fs implements the old VFS_MOUNT()
 1025          * function, since the old system call was used.
 1026          */
 1027         if (mp->mnt_op->vfs_mount == NULL) {
 1028                 printf("%s doesn't support the old mount syscall\n",
 1029                     mp->mnt_vfc->vfc_name);
 1030                 VI_LOCK(vp);
 1031                 vp->v_iflag &= ~VI_MOUNT;
 1032                 VI_UNLOCK(vp);
 1033                 if (mp->mnt_flag & MNT_UPDATE)
 1034                         vfs_unbusy(mp, td);
 1035                 else {
 1036                         mp->mnt_vfc->vfc_refcount--;
 1037                         vfs_unbusy(mp, td);
 1038 #ifdef MAC
 1039                         mac_destroy_mount(mp);
 1040 #endif
 1041                         free(mp, M_MOUNT);
 1042                 }
 1043                 vrele(vp);
 1044                 return (EOPNOTSUPP);
 1045         }
 1046 
 1047         /*
 1048          * Set the mount level flags.
 1049          */
 1050         if (fsflags & MNT_RDONLY)
 1051                 mp->mnt_flag |= MNT_RDONLY;
 1052         else if (mp->mnt_flag & MNT_RDONLY)
 1053                 mp->mnt_kern_flag |= MNTK_WANTRDWR;
 1054         mp->mnt_flag &=~ MNT_UPDATEMASK;
 1055         mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE);
 1056         /*
 1057          * Mount the filesystem.
 1058          * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
 1059          * get.  No freeing of cn_pnbuf.
 1060          */
 1061         error = VFS_MOUNT(mp, fspath, fsdata, &nd, td);
 1062         if (mp->mnt_flag & MNT_UPDATE) {
 1063                 if (mp->mnt_kern_flag & MNTK_WANTRDWR)
 1064                         mp->mnt_flag &= ~MNT_RDONLY;
 1065                 mp->mnt_flag &=~
 1066                     (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_SNAPSHOT);
 1067                 mp->mnt_kern_flag &=~ MNTK_WANTRDWR;
 1068                 if (error) {
 1069                         mp->mnt_flag = flag;
 1070                         mp->mnt_kern_flag = kern_flag;
 1071                 }
 1072                 if ((mp->mnt_flag & MNT_RDONLY) == 0) {
 1073                         if (mp->mnt_syncer == NULL)
 1074                                 error = vfs_allocate_syncvnode(mp);
 1075                 } else {
 1076                         if (mp->mnt_syncer != NULL)
 1077                                 vrele(mp->mnt_syncer);
 1078                         mp->mnt_syncer = NULL;
 1079                 }
 1080                 vfs_unbusy(mp, td);
 1081                 VI_LOCK(vp);
 1082                 vp->v_iflag &= ~VI_MOUNT;
 1083                 VI_UNLOCK(vp);
 1084                 vrele(vp);
 1085                 return (error);
 1086         }
 1087         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
 1088         /*
 1089          * Put the new filesystem on the mount list after root.
 1090          */
 1091         cache_purge(vp);
 1092         if (!error) {
 1093                 struct vnode *newdp;
 1094 
 1095                 VI_LOCK(vp);
 1096                 vp->v_iflag &= ~VI_MOUNT;
 1097                 VI_UNLOCK(vp);
 1098                 vp->v_mountedhere = mp;
 1099                 mtx_lock(&mountlist_mtx);
 1100                 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
 1101                 mtx_unlock(&mountlist_mtx);
 1102                 if (VFS_ROOT(mp, &newdp))
 1103                         panic("mount: lost mount");
 1104                 checkdirs(vp, newdp);
 1105                 vput(newdp);
 1106                 VOP_UNLOCK(vp, 0, td);
 1107                 if ((mp->mnt_flag & MNT_RDONLY) == 0)
 1108                         error = vfs_allocate_syncvnode(mp);
 1109                 vfs_unbusy(mp, td);
 1110                 if ((error = VFS_START(mp, 0, td)) != 0)
 1111                         vrele(vp);
 1112         } else {
 1113                 VI_LOCK(vp);
 1114                 vp->v_iflag &= ~VI_MOUNT;
 1115                 VI_UNLOCK(vp);
 1116                 mp->mnt_vfc->vfc_refcount--;
 1117                 vfs_unbusy(mp, td);
 1118 #ifdef MAC
 1119                 mac_destroy_mount(mp);
 1120 #endif
 1121                 free(mp, M_MOUNT);
 1122                 vput(vp);
 1123         }
 1124         return (error);
 1125 }
 1126 
 1127 /*
 1128  * Scan all active processes to see if any of them have a current
 1129  * or root directory of `olddp'. If so, replace them with the new
 1130  * mount point.
 1131  */
 1132 static void
 1133 checkdirs(olddp, newdp)
 1134         struct vnode *olddp, *newdp;
 1135 {
 1136         struct filedesc *fdp;
 1137         struct proc *p;
 1138         int nrele;
 1139 
 1140         if (vrefcnt(olddp) == 1)
 1141                 return;
 1142         sx_slock(&allproc_lock);
 1143         LIST_FOREACH(p, &allproc, p_list) {
 1144                 PROC_LOCK(p);
 1145                 fdp = p->p_fd;
 1146                 if (fdp == NULL) {
 1147                         PROC_UNLOCK(p);
 1148                         continue;
 1149                 }
 1150                 nrele = 0;
 1151                 FILEDESC_LOCK(fdp);
 1152                 if (fdp->fd_cdir == olddp) {
 1153                         VREF(newdp);
 1154                         fdp->fd_cdir = newdp;
 1155                         nrele++;
 1156                 }
 1157                 if (fdp->fd_rdir == olddp) {
 1158                         VREF(newdp);
 1159                         fdp->fd_rdir = newdp;
 1160                         nrele++;
 1161                 }
 1162                 FILEDESC_UNLOCK(fdp);
 1163                 PROC_UNLOCK(p);
 1164                 while (nrele--)
 1165                         vrele(olddp);
 1166         }
 1167         sx_sunlock(&allproc_lock);
 1168         if (rootvnode == olddp) {
 1169                 vrele(rootvnode);
 1170                 VREF(newdp);
 1171                 rootvnode = newdp;
 1172         }
 1173 }
 1174 
 1175 /*
 1176  * Unmount a filesystem.
 1177  *
 1178  * Note: unmount takes a path to the vnode mounted on as argument,
 1179  * not special file (as before).
 1180  */
 1181 #ifndef _SYS_SYSPROTO_H_
 1182 struct unmount_args {
 1183         char    *path;
 1184         int     flags;
 1185 };
 1186 #endif
 1187 /* ARGSUSED */
 1188 int
 1189 unmount(td, uap)
 1190         struct thread *td;
 1191         register struct unmount_args /* {
 1192                 char *path;
 1193                 int flags;
 1194         } */ *uap;
 1195 {
 1196         register struct vnode *vp;
 1197         struct mount *mp;
 1198         int error;
 1199         struct nameidata nd;
 1200 
 1201         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
 1202             uap->path, td);
 1203         if ((error = namei(&nd)) != 0)
 1204                 return (error);
 1205         vp = nd.ni_vp;
 1206         NDFREE(&nd, NDF_ONLY_PNBUF);
 1207         mp = vp->v_mount;
 1208 
 1209         /*
 1210          * Only root, or the user that did the original mount is
 1211          * permitted to unmount this filesystem.
 1212          */
 1213         if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) {
 1214                 error = suser(td);
 1215                 if (error) {
 1216                         vput(vp);
 1217                         return (error);
 1218                 }
 1219         }
 1220 
 1221         /*
 1222          * Don't allow unmounting the root filesystem.
 1223          */
 1224         if (mp->mnt_flag & MNT_ROOTFS) {
 1225                 vput(vp);
 1226                 return (EINVAL);
 1227         }
 1228 
 1229         /*
 1230          * Must be the root of the filesystem
 1231          */
 1232         if ((vp->v_vflag & VV_ROOT) == 0) {
 1233                 vput(vp);
 1234                 return (EINVAL);
 1235         }
 1236         vput(vp);
 1237         return (dounmount(mp, uap->flags, td));
 1238 }
 1239 
 1240 /*
 1241  * Do the actual filesystem unmount.
 1242  */
 1243 int
 1244 dounmount(mp, flags, td)
 1245         struct mount *mp;
 1246         int flags;
 1247         struct thread *td;
 1248 {
 1249         struct vnode *coveredvp, *fsrootvp;
 1250         int error;
 1251         int async_flag;
 1252 
 1253         mtx_lock(&mountlist_mtx);
 1254         if (mp->mnt_kern_flag & MNTK_UNMOUNT) {
 1255                 mtx_unlock(&mountlist_mtx);
 1256                 return (EBUSY);
 1257         }
 1258         mp->mnt_kern_flag |= MNTK_UNMOUNT;
 1259         /* Allow filesystems to detect that a forced unmount is in progress. */
 1260         if (flags & MNT_FORCE)
 1261                 mp->mnt_kern_flag |= MNTK_UNMOUNTF;
 1262         error = lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK |
 1263             ((flags & MNT_FORCE) ? 0 : LK_NOWAIT), &mountlist_mtx, td);
 1264         if (error) {
 1265                 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF);
 1266                 if (mp->mnt_kern_flag & MNTK_MWAIT)
 1267                         wakeup(mp);
 1268                 return (error);
 1269         }
 1270         vn_start_write(NULL, &mp, V_WAIT);
 1271 
 1272         if (mp->mnt_flag & MNT_EXPUBLIC)
 1273                 vfs_setpublicfs(NULL, NULL, NULL);
 1274 
 1275         vfs_msync(mp, MNT_WAIT);
 1276         async_flag = mp->mnt_flag & MNT_ASYNC;
 1277         mp->mnt_flag &=~ MNT_ASYNC;
 1278         cache_purgevfs(mp);     /* remove cache entries for this file sys */
 1279         if (mp->mnt_syncer != NULL)
 1280                 vrele(mp->mnt_syncer);
 1281         /* Move process cdir/rdir refs on fs root to underlying vnode. */
 1282         if (VFS_ROOT(mp, &fsrootvp) == 0) {
 1283                 if (mp->mnt_vnodecovered != NULL)
 1284                         checkdirs(fsrootvp, mp->mnt_vnodecovered);
 1285                 if (fsrootvp == rootvnode) {
 1286                         vrele(rootvnode);
 1287                         rootvnode = NULL;
 1288                 }
 1289                 vput(fsrootvp);
 1290         }
 1291         if (((mp->mnt_flag & MNT_RDONLY) ||
 1292              (error = VFS_SYNC(mp, MNT_WAIT, td->td_ucred, td)) == 0) ||
 1293             (flags & MNT_FORCE)) {
 1294                 error = VFS_UNMOUNT(mp, flags, td);
 1295         }
 1296         vn_finished_write(mp);
 1297         if (error) {
 1298                 /* Undo cdir/rdir and rootvnode changes made above. */
 1299                 if (VFS_ROOT(mp, &fsrootvp) == 0) {
 1300                         if (mp->mnt_vnodecovered != NULL)
 1301                                 checkdirs(mp->mnt_vnodecovered, fsrootvp);
 1302                         if (rootvnode == NULL) {
 1303                                 rootvnode = fsrootvp;
 1304                                 vref(rootvnode);
 1305                         }
 1306                         vput(fsrootvp);
 1307                 }
 1308                 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL)
 1309                         (void) vfs_allocate_syncvnode(mp);
 1310                 mtx_lock(&mountlist_mtx);
 1311                 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF);
 1312                 mp->mnt_flag |= async_flag;
 1313                 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK,
 1314                     &mountlist_mtx, td);
 1315                 if (mp->mnt_kern_flag & MNTK_MWAIT)
 1316                         wakeup(mp);
 1317                 return (error);
 1318         }
 1319         crfree(mp->mnt_cred);
 1320         mtx_lock(&mountlist_mtx);
 1321         TAILQ_REMOVE(&mountlist, mp, mnt_list);
 1322         if ((coveredvp = mp->mnt_vnodecovered) != NULL)
 1323                 coveredvp->v_mountedhere = NULL;
 1324         mp->mnt_vfc->vfc_refcount--;
 1325         if (!TAILQ_EMPTY(&mp->mnt_nvnodelist))
 1326                 panic("unmount: dangling vnode");
 1327         lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_mtx, td);
 1328         lockdestroy(&mp->mnt_lock);
 1329         if (coveredvp != NULL)
 1330                 vrele(coveredvp);
 1331         if (mp->mnt_kern_flag & MNTK_MWAIT)
 1332                 wakeup(mp);
 1333 #ifdef MAC
 1334         mac_destroy_mount(mp);
 1335 #endif
 1336         if (mp->mnt_op->vfs_mount == NULL)
 1337                 vfs_freeopts(mp->mnt_opt);
 1338         free(mp, M_MOUNT);
 1339         return (0);
 1340 }
 1341 
 1342 /*
 1343  * Lookup a filesystem type, and if found allocate and initialize
 1344  * a mount structure for it.
 1345  *
 1346  * Devname is usually updated by mount(8) after booting.
 1347  */
 1348 int
 1349 vfs_rootmountalloc(fstypename, devname, mpp)
 1350         char *fstypename;
 1351         char *devname;
 1352         struct mount **mpp;
 1353 {
 1354         struct thread *td = curthread;  /* XXX */
 1355         struct vfsconf *vfsp;
 1356         struct mount *mp;
 1357 
 1358         if (fstypename == NULL)
 1359                 return (ENODEV);
 1360         for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
 1361                 if (!strcmp(vfsp->vfc_name, fstypename))
 1362                         break;
 1363         if (vfsp == NULL)
 1364                 return (ENODEV);
 1365         mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO);
 1366         lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE);
 1367         (void)vfs_busy(mp, LK_NOWAIT, 0, td);
 1368         TAILQ_INIT(&mp->mnt_nvnodelist);
 1369         TAILQ_INIT(&mp->mnt_reservedvnlist);
 1370         mp->mnt_vfc = vfsp;
 1371         mp->mnt_op = vfsp->vfc_vfsops;
 1372         mp->mnt_flag = MNT_RDONLY;
 1373         mp->mnt_vnodecovered = NULLVP;
 1374         mp->mnt_cred = crdup(td->td_ucred);
 1375         vfsp->vfc_refcount++;
 1376         mp->mnt_iosize_max = DFLTPHYS;
 1377         mp->mnt_stat.f_type = vfsp->vfc_typenum;
 1378         mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
 1379         strlcpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
 1380         mp->mnt_stat.f_mntonname[0] = '/';
 1381         mp->mnt_stat.f_mntonname[1] = 0;
 1382         strlcpy(mp->mnt_stat.f_mntfromname, devname, MNAMELEN);
 1383 #ifdef MAC
 1384         mac_init_mount(mp);
 1385         mac_create_mount(td->td_ucred, mp);
 1386 #endif
 1387         *mpp = mp;
 1388         return (0);
 1389 }
 1390 
 1391 /*
 1392  * Find and mount the root filesystem
 1393  */
 1394 void
 1395 vfs_mountroot(void)
 1396 {
 1397         char            *cp;
 1398         int             i, error;
 1399 
 1400         g_waitidle();   
 1401 
 1402         /* 
 1403          * The root filesystem information is compiled in, and we are
 1404          * booted with instructions to use it.
 1405          */
 1406 #ifdef ROOTDEVNAME
 1407         if ((boothowto & RB_DFLTROOT) && 
 1408             !vfs_mountroot_try(ROOTDEVNAME))
 1409                 return;
 1410 #endif
 1411         /* 
 1412          * We are booted with instructions to prompt for the root filesystem,
 1413          * or to use the compiled-in default when it doesn't exist.
 1414          */
 1415         if (boothowto & (RB_DFLTROOT | RB_ASKNAME)) {
 1416                 if (!vfs_mountroot_ask())
 1417                         return;
 1418         }
 1419 
 1420         /*
 1421          * We've been given the generic "use CDROM as root" flag.  This is
 1422          * necessary because one media may be used in many different
 1423          * devices, so we need to search for them.
 1424          */
 1425         if (boothowto & RB_CDROM) {
 1426                 for (i = 0; cdrom_rootdevnames[i] != NULL; i++) {
 1427                         if (!vfs_mountroot_try(cdrom_rootdevnames[i]))
 1428                                 return;
 1429                 }
 1430         }
 1431 
 1432         /*
 1433          * Try to use the value read by the loader from /etc/fstab, or
 1434          * supplied via some other means.  This is the preferred 
 1435          * mechanism.
 1436          */
 1437         if ((cp = getenv("vfs.root.mountfrom")) != NULL) {
 1438                 error = vfs_mountroot_try(cp);
 1439                 freeenv(cp);
 1440                 if (!error)
 1441                         return;
 1442         }
 1443 
 1444         /* 
 1445          * Try values that may have been computed by the machine-dependant
 1446          * legacy code.
 1447          */
 1448         if (!vfs_mountroot_try(rootdevnames[0]))
 1449                 return;
 1450         if (!vfs_mountroot_try(rootdevnames[1]))
 1451                 return;
 1452 
 1453         /*
 1454          * If we have a compiled-in default, and haven't already tried it, try
 1455          * it now.
 1456          */
 1457 #ifdef ROOTDEVNAME
 1458         if (!(boothowto & RB_DFLTROOT))
 1459                 if (!vfs_mountroot_try(ROOTDEVNAME))
 1460                         return;
 1461 #endif
 1462 
 1463         /* 
 1464          * Everything so far has failed, prompt on the console if we haven't
 1465          * already tried that.
 1466          */
 1467         if (!(boothowto & (RB_DFLTROOT | RB_ASKNAME)) && !vfs_mountroot_ask())
 1468                 return;
 1469         panic("Root mount failed, startup aborted.");
 1470 }
 1471 
 1472 /*
 1473  * Mount (mountfrom) as the root filesystem.
 1474  */
 1475 static int
 1476 vfs_mountroot_try(char *mountfrom)
 1477 {
 1478         struct mount    *mp;
 1479         char            *vfsname, *path;
 1480         const char      *devname;
 1481         int             error;
 1482         char            patt[32];
 1483         int             s;
 1484 
 1485         vfsname = NULL;
 1486         path    = NULL;
 1487         mp      = NULL;
 1488         error   = EINVAL;
 1489 
 1490         if (mountfrom == NULL)
 1491                 return(error);          /* don't complain */
 1492 
 1493         s = splcam();                   /* Overkill, but annoying without it */
 1494         printf("Mounting root from %s\n", mountfrom);
 1495         splx(s);
 1496 
 1497         /* parse vfs name and path */
 1498         vfsname = malloc(MFSNAMELEN, M_MOUNT, M_WAITOK);
 1499         path = malloc(MNAMELEN, M_MOUNT, M_WAITOK);
 1500         vfsname[0] = path[0] = 0;
 1501         sprintf(patt, "%%%d[a-z0-9]:%%%zds", MFSNAMELEN, MNAMELEN);
 1502         if (sscanf(mountfrom, patt, vfsname, path) < 1)
 1503                 goto done;
 1504 
 1505         /* allocate a root mount */
 1506         error = vfs_rootmountalloc(vfsname, path[0] != 0 ? path : ROOTNAME,
 1507                                    &mp);
 1508         if (error != 0) {
 1509                 printf("Can't allocate root mount for filesystem '%s': %d\n",
 1510                        vfsname, error);
 1511                 goto done;
 1512         }
 1513         mp->mnt_flag |= MNT_ROOTFS;
 1514 
 1515         /* do our best to set rootdev */
 1516         if ((path[0] != 0) && setrootbyname(path))
 1517                 printf("setrootbyname failed\n");
 1518 
 1519         /* If the root device is a type "memory disk", mount RW */
 1520         if (rootdev != NODEV && devsw(rootdev) != NULL) {
 1521                 devname = devtoname(rootdev);
 1522                 if (devname[0] == 'm' && devname[1] == 'd')
 1523                         mp->mnt_flag &= ~MNT_RDONLY;
 1524         }
 1525 
 1526         /* 
 1527          * Set the mount path to be something useful, because the
 1528          * filesystem code isn't responsible now for initialising
 1529          * f_mntonname unless they want to override the default
 1530          * (which is `path'.)
 1531          */
 1532         strlcpy(mp->mnt_stat.f_mntonname, "/", MNAMELEN);
 1533 
 1534         error = VFS_MOUNT(mp, NULL, NULL, NULL, curthread);
 1535 
 1536 done:
 1537         if (vfsname != NULL)
 1538                 free(vfsname, M_MOUNT);
 1539         if (path != NULL)
 1540                 free(path, M_MOUNT);
 1541         if (error != 0) {
 1542                 if (mp != NULL) {
 1543                         vfs_unbusy(mp, curthread);
 1544 #ifdef MAC
 1545                         mac_destroy_mount(mp);
 1546 #endif
 1547                         free(mp, M_MOUNT);
 1548                 }
 1549                 printf("Root mount failed: %d\n", error);
 1550         } else {
 1551 
 1552                 /* register with list of mounted filesystems */
 1553                 mtx_lock(&mountlist_mtx);
 1554                 TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list);
 1555                 mtx_unlock(&mountlist_mtx);
 1556 
 1557                 /* sanity check system clock against root fs timestamp */
 1558                 inittodr(mp->mnt_time);
 1559                 vfs_unbusy(mp, curthread);
 1560                 error = VFS_START(mp, 0, curthread);
 1561         }
 1562         return(error);
 1563 }
 1564 
 1565 /*
 1566  * Spin prompting on the console for a suitable root filesystem
 1567  */
 1568 static int
 1569 vfs_mountroot_ask(void)
 1570 {
 1571         char name[128];
 1572         int i;
 1573         dev_t dev;
 1574 
 1575         for(;;) {
 1576                 printf("\nManual root filesystem specification:\n");
 1577                 printf("  <fstype>:<device>  Mount <device> using filesystem <fstype>\n");
 1578 #if defined(__i386__) || defined(__ia64__)
 1579                 printf("                       eg. ufs:da0s1a\n");
 1580 #else
 1581                 printf("                       eg. ufs:da0a\n");
 1582 #endif
 1583                 printf("  ?                  List valid disk boot devices\n");
 1584                 printf("  <empty line>       Abort manual input\n");
 1585                 printf("\nmountroot> ");
 1586                 gets(name);
 1587                 if (name[0] == 0)
 1588                         return(1);
 1589                 if (name[0] == '?') {
 1590                         if (!g_dev_print()) {
 1591                                 printf("Possibly valid devices for 'ufs' root:\n");
 1592                                 for (i = 0; i < NUMCDEVSW; i++) {
 1593                                         dev = makedev(i, 0);
 1594                                         if (devsw(dev) != NULL)
 1595                                                 printf(" \"%s\"", devsw(dev)->d_name);
 1596                                 }
 1597                         }
 1598                         printf("\n");
 1599                         continue;
 1600                 }
 1601                 if (!vfs_mountroot_try(name))
 1602                         return(0);
 1603         }
 1604 }
 1605 
 1606 /*
 1607  * Local helper function for vfs_mountroot_ask.
 1608  */
 1609 static void
 1610 gets(char *cp)
 1611 {
 1612         char *lp;
 1613         int c;
 1614 
 1615         lp = cp;
 1616         for (;;) {
 1617                 printf("%c", c = cngetc() & 0177);
 1618                 switch (c) {
 1619                 case -1:
 1620                 case '\n':
 1621                 case '\r':
 1622                         *lp++ = '\0';
 1623                         return;
 1624                 case '\b':
 1625                 case '\177':
 1626                         if (lp > cp) {
 1627                                 printf(" \b");
 1628                                 lp--;
 1629                         }
 1630                         continue;
 1631                 case '#':
 1632                         lp--;
 1633                         if (lp < cp)
 1634                                 lp = cp;
 1635                         continue;
 1636                 case '@':
 1637                 case 'u' & 037:
 1638                         lp = cp;
 1639                         printf("%c", '\n');
 1640                         continue;
 1641                 default:
 1642                         *lp++ = c;
 1643                 }
 1644         }
 1645 }
 1646 
 1647 /*
 1648  * Convert a given name to the dev_t of the disk-like device
 1649  * it refers to.
 1650  */
 1651 dev_t
 1652 getdiskbyname(char *name) {
 1653         char *cp;
 1654         dev_t dev;
 1655 
 1656         cp = name;
 1657         if (!bcmp(cp, "/dev/", 5))
 1658                 cp += 5;
 1659 
 1660         dev = NODEV;
 1661         EVENTHANDLER_INVOKE(dev_clone, cp, strlen(cp), &dev);
 1662         return (dev);
 1663 }
 1664 
 1665 /*
 1666  * Set rootdev to match (name), given that we expect it to
 1667  * refer to a disk-like device.
 1668  */
 1669 static int
 1670 setrootbyname(char *name)
 1671 {
 1672         dev_t diskdev;
 1673 
 1674         diskdev = getdiskbyname(name);
 1675         if (diskdev != NODEV) {
 1676                 rootdev = diskdev;
 1677                 return (0);
 1678         }
 1679 
 1680         return (1);
 1681 }
 1682 
 1683 /* Show the dev_t for a disk specified by name */
 1684 #ifdef DDB
 1685 DB_SHOW_COMMAND(disk, db_getdiskbyname)
 1686 {
 1687         dev_t dev;
 1688 
 1689         if (modif[0] == '\0') {
 1690                 db_error("usage: show disk/devicename");
 1691                 return;
 1692         }
 1693         dev = getdiskbyname(modif);
 1694         if (dev != NODEV)
 1695                 db_printf("dev_t = %p\n", dev);
 1696         else
 1697                 db_printf("No disk device matched.\n");
 1698 }
 1699 #endif
 1700 
 1701 /*
 1702  * Get a mount option by its name.
 1703  *
 1704  * Return 0 if the option was found, ENOENT otherwise.
 1705  * If len is non-NULL it will be filled with the length
 1706  * of the option. If buf is non-NULL, it will be filled
 1707  * with the address of the option.
 1708  */
 1709 int
 1710 vfs_getopt(opts, name, buf, len)
 1711         struct vfsoptlist *opts;
 1712         const char *name;
 1713         void **buf;
 1714         int *len;
 1715 {
 1716         struct vfsopt *opt;
 1717 
 1718         TAILQ_FOREACH(opt, opts, link) {
 1719                 if (strcmp(name, opt->name) == 0) {
 1720                         if (len != NULL)
 1721                                 *len = opt->len;
 1722                         if (buf != NULL)
 1723                                 *buf = opt->value;
 1724                         return (0);
 1725                 }
 1726         }
 1727         return (ENOENT);
 1728 }
 1729 
 1730 /*
 1731  * Find and copy a mount option.
 1732  *
 1733  * The size of the buffer has to be specified
 1734  * in len, if it is not the same length as the
 1735  * mount option, EINVAL is returned.
 1736  * Returns ENOENT if the option is not found.
 1737  */
 1738 int
 1739 vfs_copyopt(opts, name, dest, len)
 1740         struct vfsoptlist *opts;
 1741         const char *name;
 1742         void *dest;
 1743         int len;
 1744 {
 1745         struct vfsopt *opt;
 1746 
 1747         TAILQ_FOREACH(opt, opts, link) {
 1748                 if (strcmp(name, opt->name) == 0) {
 1749                         if (len != opt->len)
 1750                                 return (EINVAL);
 1751                         bcopy(opt->value, dest, opt->len);
 1752                         return (0);
 1753                 }
 1754         }
 1755         return (ENOENT);
 1756 }

Cache object: 6591e6f0aeab811c0d9033e4fb210462


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.