root/ufs/mfs/mfs_vfsops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mfs_mountroot
  2. mfs_initminiroot
  3. mfs_mount
  4. mfs_start
  5. mfs_statfs
  6. mfs_checkexp
  7. mfs_init

    1 /*      $OpenBSD: mfs_vfsops.c,v 1.34 2006/06/25 15:01:54 sturm Exp $   */
    2 /*      $NetBSD: mfs_vfsops.c,v 1.10 1996/02/09 22:31:28 christos Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1989, 1990, 1993, 1994
    6  *      The Regents of the University of California.  All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the University nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  *      @(#)mfs_vfsops.c        8.4 (Berkeley) 4/16/94
   33  */
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/time.h>
   38 #include <sys/kernel.h>
   39 #include <sys/proc.h>
   40 #include <sys/buf.h>
   41 #include <sys/mount.h>
   42 #include <sys/signalvar.h>
   43 #include <sys/vnode.h>
   44 #include <sys/malloc.h>
   45 #include <sys/kthread.h>
   46 
   47 #include <ufs/ufs/quota.h>
   48 #include <ufs/ufs/inode.h>
   49 #include <ufs/ufs/ufsmount.h>
   50 #include <ufs/ufs/ufs_extern.h>
   51 
   52 #include <ufs/ffs/fs.h>
   53 #include <ufs/ffs/ffs_extern.h>
   54 
   55 #include <ufs/mfs/mfsnode.h>
   56 #include <ufs/mfs/mfs_extern.h>
   57 
   58 caddr_t mfs_rootbase;   /* address of mini-root in kernel virtual memory */
   59 u_long  mfs_rootsize;   /* size of mini-root in bytes */
   60 
   61 static  int mfs_minor;  /* used for building internal dev_t */
   62 
   63 extern int (**mfs_vnodeop_p)(void *);
   64 
   65 /*
   66  * mfs vfs operations.
   67  */
   68 const struct vfsops mfs_vfsops = {
   69         mfs_mount,
   70         mfs_start,
   71         ffs_unmount,
   72         ufs_root,
   73         ufs_quotactl,
   74         mfs_statfs,
   75         ffs_sync,
   76         ffs_vget,
   77         ffs_fhtovp,
   78         ffs_vptofh,
   79         mfs_init,
   80         ffs_sysctl,
   81         mfs_checkexp
   82 };
   83 
   84 /*
   85  * Called by main() when mfs is going to be mounted as root.
   86  */
   87 
   88 int
   89 mfs_mountroot(void)
   90 {
   91         struct fs *fs;
   92         struct mount *mp;
   93         struct proc *p = curproc;
   94         struct ufsmount *ump;
   95         struct mfsnode *mfsp;
   96         int error;
   97 
   98         if ((error = bdevvp(swapdev, &swapdev_vp)) ||
   99             (error = bdevvp(rootdev, &rootvp))) {
  100                 printf("mfs_mountroot: can't setup bdevvp's");
  101                 return (error);
  102         }
  103         if ((error = vfs_rootmountalloc("mfs", "mfs_root", &mp)) != 0)
  104                 return (error);
  105         mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK);
  106         rootvp->v_data = mfsp;
  107         rootvp->v_op = mfs_vnodeop_p;
  108         rootvp->v_tag = VT_MFS;
  109         mfsp->mfs_baseoff = mfs_rootbase;
  110         mfsp->mfs_size = mfs_rootsize;
  111         mfsp->mfs_vnode = rootvp;
  112         mfsp->mfs_pid = p->p_pid;
  113         mfsp->mfs_buflist = (struct buf *)0;
  114         if ((error = ffs_mountfs(rootvp, mp, p)) != 0) {
  115                 mp->mnt_vfc->vfc_refcount--;
  116                 vfs_unbusy(mp);
  117                 free(mp, M_MOUNT);
  118                 free(mfsp, M_MFSNODE);
  119                 return (error);
  120         }
  121 
  122         CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
  123         ump = VFSTOUFS(mp);
  124         fs = ump->um_fs;
  125         (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
  126         (void)ffs_statfs(mp, &mp->mnt_stat, p);
  127         vfs_unbusy(mp);
  128         inittodr((time_t)0);
  129 
  130         return (0);
  131 }
  132 
  133 /*
  134  * This is called early in boot to set the base address and size
  135  * of the mini-root.
  136  */
  137 int
  138 mfs_initminiroot(caddr_t base)
  139 {
  140         struct fs *fs = (struct fs *)(base + SBOFF);
  141         extern int (*mountroot)(void);
  142 
  143         /* check for valid super block */
  144         if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
  145             fs->fs_bsize < sizeof(struct fs))
  146                 return (0);
  147         mountroot = mfs_mountroot;
  148         mfs_rootbase = base;
  149         mfs_rootsize = fs->fs_fsize * fs->fs_size;
  150         rootdev = makedev(255, mfs_minor);
  151         mfs_minor++;
  152         return (mfs_rootsize);
  153 }
  154 
  155 /*
  156  * VFS Operations.
  157  *
  158  * mount system call
  159  */
  160 /* ARGSUSED */
  161 int
  162 mfs_mount(struct mount *mp, const char *path, void *data,
  163     struct nameidata *ndp, struct proc *p)
  164 {
  165         struct vnode *devvp;
  166         struct mfs_args args;
  167         struct ufsmount *ump;
  168         struct fs *fs;
  169         struct mfsnode *mfsp;
  170         size_t size;
  171         int flags, error;
  172 
  173         error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args));
  174         if (error)
  175                 return (error);
  176 
  177         /*
  178          * If updating, check whether changing from read-only to
  179          * read/write; if there is no device name, that's all we do.
  180          */
  181         if (mp->mnt_flag & MNT_UPDATE) {
  182                 ump = VFSTOUFS(mp);
  183                 fs = ump->um_fs;
  184                 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
  185                         flags = WRITECLOSE;
  186                         if (mp->mnt_flag & MNT_FORCE)
  187                                 flags |= FORCECLOSE;
  188                         error = ffs_flushfiles(mp, flags, p);
  189                         if (error)
  190                                 return (error);
  191                 }
  192                 if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR))
  193                         fs->fs_ronly = 0;
  194 #ifdef EXPORTMFS
  195                 if (args.fspec == 0)
  196                         return (vfs_export(mp, &ump->um_export, 
  197                             &args.export_info));
  198 #endif
  199                 return (0);
  200         }
  201         error = getnewvnode(VT_MFS, (struct mount *)0, mfs_vnodeop_p, &devvp);
  202         if (error)
  203                 return (error);
  204         devvp->v_type = VBLK;
  205         if (checkalias(devvp, makedev(255, mfs_minor), (struct mount *)0))
  206                 panic("mfs_mount: dup dev");
  207         mfs_minor++;
  208         mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK);
  209         devvp->v_data = mfsp;
  210         mfsp->mfs_baseoff = args.base;
  211         mfsp->mfs_size = args.size;
  212         mfsp->mfs_vnode = devvp;
  213         mfsp->mfs_pid = p->p_pid;
  214         mfsp->mfs_buflist = (struct buf *)0;
  215         if ((error = ffs_mountfs(devvp, mp, p)) != 0) {
  216                 mfsp->mfs_buflist = (struct buf *)-1;
  217                 vrele(devvp);
  218                 return (error);
  219         }
  220         ump = VFSTOUFS(mp);
  221         fs = ump->um_fs;
  222         (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
  223         bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
  224         bcopy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, MNAMELEN);
  225         (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
  226             &size);
  227         bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
  228         bcopy(&args, &mp->mnt_stat.mount_info.mfs_args, sizeof(args));
  229         return (0);
  230 }
  231 
  232 int     mfs_pri = PWAIT | PCATCH;               /* XXX prob. temp */
  233 
  234 /*
  235  * Used to grab the process and keep it in the kernel to service
  236  * memory filesystem I/O requests.
  237  *
  238  * Loop servicing I/O requests.
  239  * Copy the requested data into or out of the memory filesystem
  240  * address space.
  241  */
  242 /* ARGSUSED */
  243 int
  244 mfs_start(struct mount *mp, int flags, struct proc *p)
  245 {
  246         struct vnode *vp = VFSTOUFS(mp)->um_devvp;
  247         struct mfsnode *mfsp = VTOMFS(vp);
  248         struct buf *bp;
  249         caddr_t base;
  250         int sleepreturn = 0;
  251 
  252         base = mfsp->mfs_baseoff;
  253         while (mfsp->mfs_buflist != (struct buf *)-1) {
  254                 while ((bp = mfsp->mfs_buflist) != NULL) {
  255                         mfsp->mfs_buflist = bp->b_actf;
  256                         mfs_doio(bp, base);
  257                         wakeup((caddr_t)bp);
  258                 }
  259                 /*
  260                  * If a non-ignored signal is received, try to unmount.
  261                  * If that fails, clear the signal (it has been "processed"),
  262                  * otherwise we will loop here, as tsleep will always return
  263                  * EINTR/ERESTART.
  264                  */
  265                 if (sleepreturn != 0) {
  266                         if (vfs_busy(mp, VB_WRITE|VB_NOWAIT) ||
  267                             dounmount(mp, 0, p, NULL))
  268                                 CLRSIG(p, CURSIG(p));
  269                         sleepreturn = 0;
  270                         continue;
  271                 }
  272                 sleepreturn = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0);
  273         }
  274         return (0);
  275 }
  276 
  277 /*
  278  * Get file system statistics.
  279  */
  280 int
  281 mfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
  282 {
  283         int error;
  284 
  285         error = ffs_statfs(mp, sbp, p);
  286         strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
  287         if (sbp != &mp->mnt_stat)
  288                 bcopy(&mp->mnt_stat.mount_info.mfs_args,
  289                     &sbp->mount_info.mfs_args, sizeof(struct mfs_args));
  290         return (error);
  291 }
  292 
  293 /*
  294  * check export permission, not supported
  295  */
  296 /* ARGUSED */
  297 int
  298 mfs_checkexp(struct mount *mp, struct mbuf *nam, int *exflagsp,
  299     struct ucred **credanonp)
  300 {
  301         return (EOPNOTSUPP);
  302 }
  303 
  304 /*
  305  * Memory based filesystem initialization.
  306  */
  307 int
  308 mfs_init(struct vfsconf *vfsp)
  309 {
  310         return (ffs_init(vfsp));
  311 }

/* [<][>][^][v][top][bottom][index][help] */