use ffs_vget
[unix-history] / usr / src / sys / ufs / mfs / mfs_vfsops.c
index bf0e572..b480565 100644 (file)
  * Copyright (c) 1989, 1990 The Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1989, 1990 The Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  *
  *
- *     @(#)mfs_vfsops.c        7.16 (Berkeley) %G%
+ *     @(#)mfs_vfsops.c        7.26 (Berkeley) %G%
  */
 
  */
 
-#include "param.h"
-#include "time.h"
-#include "kernel.h"
-#include "user.h"
-#include "proc.h"
-#include "buf.h"
-#include "mount.h"
-#include "vnode.h"
-#include "../ufs/quota.h"
-#include "../ufs/inode.h"
-#include "../ufs/ufsmount.h"
-#include "../ufs/mfsnode.h"
-#include "../ufs/fs.h"
-
-extern struct vnodeops mfs_vnodeops;
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/buf.h>
+#include <sys/mount.h>
+#include <sys/signalvar.h>
+#include <sys/vnode.h>
+#include <sys/malloc.h>
+
+#include <ufs/ufs/quota.h>
+#include <ufs/ufs/inode.h>
+#include <ufs/ufs/ufsmount.h>
+#include <ufs/ufs/ufs_extern.h>
+
+#include <ufs/ffs/fs.h>
+#include <ufs/ffs/ffs_extern.h>
+
+#include <ufs/mfs/mfsnode.h>
+#include <ufs/mfs/mfs_extern.h>
+
+caddr_t        mfs_rootbase;   /* address of mini-root in kernel virtual memory */
+u_long mfs_rootsize;   /* size of mini-root in bytes */
+
+static int mfs_minor;  /* used for building internal dev_t */
+
+extern int (**mfs_vnodeop_p)();
 
 /*
  * mfs vfs operations.
  */
 
 /*
  * mfs vfs operations.
  */
-int mfs_mount();
-int mfs_start();
-int ufs_unmount();
-int ufs_root();
-int ufs_quotactl();
-int mfs_statfs();
-int ufs_sync();
-int ufs_fhtovp();
-int ufs_vptofh();
-int mfs_init();
-
 struct vfsops mfs_vfsops = {
        mfs_mount,
        mfs_start,
 struct vfsops mfs_vfsops = {
        mfs_mount,
        mfs_start,
-       ufs_unmount,
-       ufs_root,
+       ffs_unmount,
+       ffs_root,
        ufs_quotactl,
        mfs_statfs,
        ufs_quotactl,
        mfs_statfs,
-       ufs_sync,
-       ufs_fhtovp,
-       ufs_vptofh,
+       ffs_sync,
+       ffs_vget,
+       ffs_fhtovp,
+       ffs_vptofh,
        mfs_init,
 };
 
        mfs_init,
 };
 
+/*
+ * Called by main() when mfs is going to be mounted as root.
+ *
+ * Name is updated by mount(8) after booting.
+ */
+#define ROOTNAME       "mfs_root"
+
+mfs_mountroot()
+{
+       extern struct vnode *rootvp;
+       register struct fs *fs;
+       register struct mount *mp;
+       struct proc *p = curproc;       /* XXX */
+       struct ufsmount *ump;
+       struct mfsnode *mfsp;
+       u_int size;
+       int error;
+
+       mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
+       mp->mnt_op = &mfs_vfsops;
+       mp->mnt_flag = MNT_RDONLY;
+       mp->mnt_mounth = NULLVP;
+       mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK);
+       rootvp->v_data = mfsp;
+       rootvp->v_op = mfs_vnodeop_p;
+       rootvp->v_tag = VT_MFS;
+       mfsp->mfs_baseoff = mfs_rootbase;
+       mfsp->mfs_size = mfs_rootsize;
+       mfsp->mfs_vnode = rootvp;
+       mfsp->mfs_pid = p->p_pid;
+       mfsp->mfs_buflist = (struct buf *)0;
+       if (error = ffs_mountfs(rootvp, mp, p)) {
+               free(mp, M_MOUNT);
+               free(mfsp, M_MFSNODE);
+               return (error);
+       }
+       if (error = vfs_lock(mp)) {
+               (void)ffs_unmount(mp, 0, p);
+               free(mp, M_MOUNT);
+               free(mfsp, M_MFSNODE);
+               return (error);
+       }
+       rootfs = mp;
+       mp->mnt_next = mp;
+       mp->mnt_prev = mp;
+       mp->mnt_vnodecovered = NULLVP;
+       ump = VFSTOUFS(mp);
+       fs = ump->um_fs;
+       bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt));
+       fs->fs_fsmnt[0] = '/';
+       bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
+           MNAMELEN);
+       (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
+           &size);
+       bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+       (void)ffs_statfs(mp, &mp->mnt_stat, p);
+       vfs_unlock(mp);
+       inittodr((time_t)0);
+       return (0);
+}
+
+/*
+ * This is called early in boot to set the base address and size
+ * of the mini-root.
+ */
+mfs_initminiroot(base)
+       caddr_t base;
+{
+       struct fs *fs = (struct fs *)(base + SBOFF);
+       extern int (*mountroot)();
+
+       /* check for valid super block */
+       if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
+           fs->fs_bsize < sizeof(struct fs))
+               return (0);
+       mountroot = mfs_mountroot;
+       mfs_rootbase = base;
+       mfs_rootsize = fs->fs_fsize * fs->fs_size;
+       rootdev = makedev(255, mfs_minor++);
+       return (mfs_rootsize);
+}
+
 /*
  * VFS Operations.
  *
  * mount system call
  */
 /* ARGSUSED */
 /*
  * VFS Operations.
  *
  * mount system call
  */
 /* ARGSUSED */
-mfs_mount(mp, path, data, ndp)
+int
+mfs_mount(mp, path, data, ndp, p)
        register struct mount *mp;
        char *path;
        caddr_t data;
        struct nameidata *ndp;
        register struct mount *mp;
        char *path;
        caddr_t data;
        struct nameidata *ndp;
+       struct proc *p;
 {
        struct vnode *devvp;
        struct mfs_args args;
        struct ufsmount *ump;
        register struct fs *fs;
        register struct mfsnode *mfsp;
 {
        struct vnode *devvp;
        struct mfs_args args;
        struct ufsmount *ump;
        register struct fs *fs;
        register struct mfsnode *mfsp;
-       static int mfs_minor;
        u_int size;
        int error;
 
        u_int size;
        int error;
 
@@ -90,19 +166,20 @@ mfs_mount(mp, path, data, ndp)
        }
        if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args)))
                return (error);
        }
        if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args)))
                return (error);
-       error = getnewvnode(VT_MFS, (struct mount *)0, &mfs_vnodeops, &devvp);
+       error = getnewvnode(VT_MFS, (struct mount *)0, mfs_vnodeop_p, &devvp);
        if (error)
                return (error);
        devvp->v_type = VBLK;
        if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0))
                panic("mfs_mount: dup dev");
        if (error)
                return (error);
        devvp->v_type = VBLK;
        if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0))
                panic("mfs_mount: dup dev");
-       mfsp = VTOMFS(devvp);
+       mfsp = (struct mfsnode *)malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK);
+       devvp->v_data = mfsp;
        mfsp->mfs_baseoff = args.base;
        mfsp->mfs_size = args.size;
        mfsp->mfs_vnode = devvp;
        mfsp->mfs_baseoff = args.base;
        mfsp->mfs_size = args.size;
        mfsp->mfs_vnode = devvp;
-       mfsp->mfs_pid = u.u_procp->p_pid;
+       mfsp->mfs_pid = p->p_pid;
        mfsp->mfs_buflist = (struct buf *)0;
        mfsp->mfs_buflist = (struct buf *)0;
-       if (error = mountfs(devvp, mp)) {
+       if (error = ffs_mountfs(devvp, mp, p)) {
                mfsp->mfs_buflist = (struct buf *)-1;
                vrele(devvp);
                return (error);
                mfsp->mfs_buflist = (struct buf *)-1;
                vrele(devvp);
                return (error);
@@ -116,7 +193,7 @@ mfs_mount(mp, path, data, ndp)
        (void) copyinstr(args.name, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
                &size);
        bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
        (void) copyinstr(args.name, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
                &size);
        bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
-       (void) mfs_statfs(mp, &mp->mnt_stat);
+       (void) mfs_statfs(mp, &mp->mnt_stat, p);
        return (0);
 }
 
        return (0);
 }
 
@@ -131,15 +208,16 @@ int       mfs_pri = PWAIT | PCATCH;               /* XXX prob. temp */
  * address space.
  */
 /* ARGSUSED */
  * address space.
  */
 /* ARGSUSED */
-mfs_start(mp, flags)
+int
+mfs_start(mp, flags, p)
        struct mount *mp;
        int flags;
        struct mount *mp;
        int flags;
+       struct proc *p;
 {
        register struct vnode *vp = VFSTOUFS(mp)->um_devvp;
        register struct mfsnode *mfsp = VTOMFS(vp);
        register struct buf *bp;
        register caddr_t base;
 {
        register struct vnode *vp = VFSTOUFS(mp)->um_devvp;
        register struct mfsnode *mfsp = VTOMFS(vp);
        register struct buf *bp;
        register caddr_t base;
-       struct proc *p = u.u_procp;
        int error = 0;
 
        base = mfsp->mfs_baseoff;
        int error = 0;
 
        base = mfsp->mfs_baseoff;
@@ -156,7 +234,7 @@ mfs_start(mp, flags)
                 * EINTR/ERESTART.
                 */
                if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0))
                 * EINTR/ERESTART.
                 */
                if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0))
-                       if (dounmount(mp, MNT_NOFORCE) != 0)
+                       if (dounmount(mp, MNT_NOFORCE, p) != 0)
                                CLRSIG(p, CURSIG(p));
        }
        return (error);
                                CLRSIG(p, CURSIG(p));
        }
        return (error);
@@ -165,13 +243,14 @@ mfs_start(mp, flags)
 /*
  * Get file system statistics.
  */
 /*
  * Get file system statistics.
  */
-mfs_statfs(mp, sbp)
+mfs_statfs(mp, sbp, p)
        struct mount *mp;
        struct statfs *sbp;
        struct mount *mp;
        struct statfs *sbp;
+       struct proc *p;
 {
        int error;
 
 {
        int error;
 
-       error = ufs_statfs(mp, sbp);
+       error = ffs_statfs(mp, sbp, p);
        sbp->f_type = MOUNT_MFS;
        return (error);
 }
        sbp->f_type = MOUNT_MFS;
        return (error);
 }