summaryrefslogtreecommitdiffstats
path: root/sys/ufs/mfs/mfs_vfsops.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1995-08-28 09:19:25 +0000
committerjulian <julian@FreeBSD.org>1995-08-28 09:19:25 +0000
commitebb726ec45c12268b6b931aa636809cc9cb99a90 (patch)
tree53b6da073fd58ab81ebf18bb0642954c76b642bd /sys/ufs/mfs/mfs_vfsops.c
parent6f51a7615899188fd49e4446341be92684c778de (diff)
downloadFreeBSD-src-ebb726ec45c12268b6b931aa636809cc9cb99a90.zip
FreeBSD-src-ebb726ec45c12268b6b931aa636809cc9cb99a90.tar.gz
Reviewed by: julian with quick glances by bruce and others
Submitted by: terry (terry lambert) This is a composite of 3 patch sets submitted by terry. they are: New low-level init code that supports loadbal modules better some cleanups in the namei code to help terry in 16-bit character support some changes to the mount-root code to make it a little more modular.. NOTE: mounting root off cdrom or NFS MIGHT be broken as I haven't been able to test those cases.. certainly mounting root of disk still works just fine.. mfs should work but is untested. (tomorrows task) The low level init stuff includes a total rewrite of init_main.c to make it possible for new modules to have an init phase by simply adding an entry to a TEXT_SET (or is it DATA_SET) list. thus a new module can be added to the kernel without editing any other files other than the 'files' file.
Diffstat (limited to 'sys/ufs/mfs/mfs_vfsops.c')
-rw-r--r--sys/ufs/mfs/mfs_vfsops.c266
1 files changed, 170 insertions, 96 deletions
diff --git a/sys/ufs/mfs/mfs_vfsops.c b/sys/ufs/mfs/mfs_vfsops.c
index cc62f94..3213cea 100644
--- a/sys/ufs/mfs/mfs_vfsops.c
+++ b/sys/ufs/mfs/mfs_vfsops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)mfs_vfsops.c 8.4 (Berkeley) 4/16/94
- * $Id: mfs_vfsops.c,v 1.10 1995/08/11 11:31:18 davidg Exp $
+ * $Id: mfs_vfsops.c,v 1.11 1995/08/20 10:26:00 davidg Exp $
*/
#include <sys/param.h>
@@ -40,11 +40,17 @@
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/buf.h>
+#include <sys/mbuf.h>
+#include <sys/file.h>
+#include <sys/disklabel.h>
+#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/signalvar.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
+#include <miscfs/specfs/specdev.h>
+
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/ufsmount.h>
@@ -82,74 +88,14 @@ struct vfsops mfs_vfsops = {
VFS_SET(mfs_vfsops, mfs, MOUNT_MFS, 0);
-/*
- * Called by main() when mfs is going to be mounted as root.
- *
- * Name is updated by mount(8) after booting.
- */
-#define ROOTNAME "mfs_root"
-
-int
-mfs_mountroot()
-{
- register struct fs *fs;
- register struct mount *mp;
- struct proc *p = curproc; /* XXX */
- struct ufsmount *ump;
- struct mfsnode *mfsp;
- u_int size;
- int error;
-
- /*
- * Get vnode for rootdev.
- */
- if (bdevvp(rootdev, &rootvp))
- panic("mfs_mountroot: can't setup bdevvp for rootdev");
-
- mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
- bzero((char *)mp, (u_long)sizeof(struct mount));
- mp->mnt_op = &mfs_vfsops;
- 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);
- }
- CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
- mp->mnt_flag |= MNT_ROOTFS;
- 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);
-}
+int vfs_mountroot __P((caddr_t)); /* XXX goes away*/
/*
* This is called early in boot to set the base address and size
* of the mini-root.
+ *
+ * XXX THIS IS A DESIGN ERROR; THIS CODE SHOULD BE MOVED INTO
+ * XXX THE ROOT MOUNT CODE IN "mfs_mount"!!!
*/
int
mfs_initminiroot(base)
@@ -161,7 +107,8 @@ mfs_initminiroot(base)
if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
fs->fs_bsize < sizeof(struct fs))
return (0);
- mountroot = mfs_mountroot;
+ mountroot = vfs_mountroot; /* XXX goes away*/
+ mountrootvfsops = &mfs_vfsops;
mfs_rootbase = base;
mfs_rootsize = fs->fs_fsize * fs->fs_size;
rootdev = makedev(255, mfs_minor++);
@@ -169,10 +116,43 @@ mfs_initminiroot(base)
return (mfs_rootsize);
}
+
/*
- * VFS Operations.
+ * mfs_mount
+ *
+ * Called when mounting local physical media
+ *
+ * PARAMETERS:
+ * mountroot
+ * mp mount point structure
+ * path NULL (flag for root mount!!!)
+ * data <unused>
+ * ndp <unused>
+ * p process (user credentials check [statfs])
+ *
+ * mount
+ * mp mount point structure
+ * path path to mount point
+ * data pointer to argument struct in user space
+ * ndp mount point namei() return (used for
+ * credentials on reload), reused to look
+ * up block device.
+ * p process (user credentials check)
*
- * mount system call
+ * RETURNS: 0 Success
+ * !0 error number (errno.h)
+ *
+ * LOCK STATE:
+ *
+ * ENTRY
+ * mount point is locked
+ * EXIT
+ * mount point is locked
+ *
+ * NOTES:
+ * A NULL path can be used for a flag since the mount
+ * system call will fail with EFAULT in copyinstr in
+ * namei() if it is a genuine NULL from the user.
*/
/* ARGSUSED */
int
@@ -189,40 +169,103 @@ mfs_mount(mp, path, data, ndp, p)
register struct fs *fs;
register struct mfsnode *mfsp;
u_int size;
- int flags, error;
+ int flags, err;
+
+ /*
+ * Use NULL path to flag a root mount
+ */
+ if( path == NULL) {
+ /*
+ ***
+ * Mounting root file system
+ ***
+ */
- if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args)))
- return (error);
+ /* Get vnode for root device*/
+ if( bdevvp( rootdev, &rootvp))
+ panic("mfs_mountroot: can't setup bdevvp for rootdev");
+
+ /*
+ * FS specific handling
+ */
+ 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;
+
+ /*
+ * Attempt mount
+ */
+ if( (err = ffs_mountfs(rootvp, mp, p)) != 0 ) {
+ /* fs specific cleanup (if any)*/
+ rootvp->v_data = NULL;
+ free(mfsp, M_MFSNODE);
+ goto error_1;
+ }
+
+ goto dostatfs; /* success*/
+ }
+
+ /*
+ ***
+ * Mounting non-root file system or updating a file system
+ ***
+ */
+
+ /* copy in user arguments*/
+ if (err = copyin(data, (caddr_t)&args, sizeof (struct mfs_args)))
+ goto error_1;
/*
* If updating, check whether changing from read-only to
* read/write; if there is no device name, that's all we do.
*/
if (mp->mnt_flag & MNT_UPDATE) {
+ /*
+ ********************
+ * UPDATE
+ ********************
+ */
ump = VFSTOUFS(mp);
fs = ump->um_fs;
if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
- if (vfs_busy(mp))
- return (EBUSY);
- error = ffs_flushfiles(mp, flags, p);
+ if (vfs_busy(mp)) {
+ err = EBUSY;
+ goto error_1;
+ }
+ err = ffs_flushfiles(mp, flags, p);
vfs_unbusy(mp);
- if (error)
- return (error);
+ if (err)
+ goto error_1;
}
if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR))
fs->fs_ronly = 0;
#ifdef EXPORTMFS
- if (args.fspec == 0)
- return (vfs_export(mp, &ump->um_export, &args.export));
+ /* if not updating name...*/
+ if (args.fspec == 0) {
+ /*
+ * Process export requests. Jumping to "success"
+ * will return the vfs_export() error code.
+ */
+ err = vfs_export(mp, &ump->um_export, &args.export);
+ goto success;
+ }
#endif
- return (0);
+
+ /* XXX MFS does not support name updating*/
+ goto success;
}
- error = getnewvnode(VT_MFS, (struct mount *)0, mfs_vnodeop_p, &devvp);
- if (error)
- return (error);
+ err = getnewvnode(VT_MFS, (struct mount *)0, mfs_vnodeop_p, &devvp);
+ if (err)
+ goto error_1;
devvp->v_type = VBLK;
if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0))
panic("mfs_mount: dup dev");
@@ -233,24 +276,55 @@ mfs_mount(mp, path, data, ndp, p)
mfsp->mfs_vnode = devvp;
mfsp->mfs_pid = p->p_pid;
mfsp->mfs_buflist = (struct buf *)0;
- if (error = ffs_mountfs(devvp, mp, p)) {
+
+ /*
+ * Since this is a new mount, we want the names for
+ * the device and the mount point copied in. If an
+ * error occurs, the mountpoint is discarded by the
+ * upper level code.
+ */
+ /* Save "last mounted on" info for mount point (NULL pad)*/
+ copyinstr( path, /* mount point*/
+ mp->mnt_stat.f_mntonname, /* save area*/
+ MNAMELEN - 1, /* max size*/
+ &size); /* real size*/
+ bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
+
+ /* Save "mounted from" info for mount point (NULL pad)*/
+ copyinstr( args.fspec, /* device name*/
+ mp->mnt_stat.f_mntfromname, /* save area*/
+ MNAMELEN - 1, /* max size*/
+ &size); /* real size*/
+ bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+
+ if (err = ffs_mountfs(devvp, mp, p)) {
mfsp->mfs_buflist = (struct buf *)-1;
- vrele(devvp);
- return (error);
+ goto error_2;
}
- ump = VFSTOUFS(mp);
- fs = ump->um_fs;
- (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
- bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
- bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
- MNAMELEN);
- (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
- &size);
- bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
- (void) mfs_statfs(mp, &mp->mnt_stat, p);
- return (0);
+
+dostatfs:
+ /*
+ * Initialize FS stat information in mount struct; uses both
+ * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname
+ *
+ * This code is common to root and non-root mounts
+ */
+ (void) VFS_STATFS(mp, &mp->mnt_stat, p);
+
+ goto success;
+
+error_2: /* error with devvp held*/
+
+ /* release devvp before failing*/
+ vrele(devvp);
+
+error_1: /* no state to back out*/
+
+success:
+ return( err);
}
+
int mfs_pri = PWAIT | PCATCH; /* XXX prob. temp */
/*
OpenPOWER on IntegriCloud