summaryrefslogtreecommitdiffstats
path: root/sys/ufs
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
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')
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c324
-rw-r--r--sys/ufs/lfs/lfs_vfsops.c118
-rw-r--r--sys/ufs/mfs/mfs_extern.h4
-rw-r--r--sys/ufs/mfs/mfs_vfsops.c266
-rw-r--r--sys/ufs/ufs/dir.h13
-rw-r--r--sys/ufs/ufs/ufs_lookup.c50
-rw-r--r--sys/ufs/ufs/ufs_vnops.c10
7 files changed, 515 insertions, 270 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 19c78cf..78cbfda 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94
- * $Id: ffs_vfsops.c,v 1.26 1995/08/06 11:56:42 davidg Exp $
+ * $Id: ffs_vfsops.c,v 1.27 1995/08/11 11:31:15 davidg Exp $
*/
#include <sys/param.h>
@@ -87,85 +87,103 @@ VFS_SET(ufs_vfsops, ufs, MOUNT_UFS, 0);
extern u_long nextgennumber;
+
/*
- * Called by main() when ufs is going to be mounted as root.
+ * ffs_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)
+ *
+ * RETURNS: 0 Success
+ * !0 error number (errno.h)
+ *
+ * LOCK STATE:
+ *
+ * ENTRY
+ * mount point is locked
+ * EXIT
+ * mount point is locked
*
- * Name is updated by mount(8) after booting.
+ * 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.
*/
-#define ROOTNAME "root_device"
-
int
-ffs_mountroot()
+ffs_mount( mp, path, data, ndp, p)
+ register struct mount *mp; /* mount struct pointer*/
+ char *path; /* path to mount point*/
+ caddr_t data; /* arguments to FS specific mount*/
+ struct nameidata *ndp; /* mount point credentials*/
+ struct proc *p; /* process requesting mount*/
{
+ u_int size;
+ int err = 0;
+ struct vnode *devvp;
+
+ struct ufs_args args;
+ struct ufsmount *ump = 0;
register struct fs *fs;
- register struct mount *mp;
- struct proc *p = curproc; /* XXX */
- struct ufsmount *ump;
- u_int size;
- int error;
+ int flags;
/*
- * Get vnode for rootdev.
+ * Use NULL path to flag a root mount
*/
- if (bdevvp(rootdev, &rootvp))
- panic("ffs_mountroot: can't setup bdevvp for root");
-
- mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
- bzero((char *)mp, (u_long)sizeof(struct mount));
- mp->mnt_op = &ufs_vfsops;
- mp->mnt_flag = MNT_RDONLY;
- error = ffs_mountfs(rootvp, mp, p);
- if (error) {
- free(mp, M_MOUNT);
- return (error);
- }
- error = vfs_lock(mp);
- if (error) {
- (void)ffs_unmount(mp, 0, p);
- free(mp, M_MOUNT);
- return (error);
+ if( path == NULL) {
+ /*
+ ***
+ * Mounting root file system
+ ***
+ */
+
+ /* Get vnode for root device*/
+ if( bdevvp( rootdev, &rootvp))
+ panic("ffs_mountroot: can't setup bdevvp for root");
+
+ /*
+ * FS specific handling
+ */
+ mp->mnt_flag |= MNT_RDONLY; /* XXX globally applicable?*/
+
+ /*
+ * Attempt mount
+ */
+ if( ( err = ffs_mountfs(rootvp, mp, p)) != 0) {
+ /* fs specific cleanup (if any)*/
+ goto error_1;
+ }
+
+ goto dostatfs; /* success*/
+
}
- 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(fs->fs_time);
- return (0);
-}
-/*
- * VFS Operations.
- *
- * mount system call
- */
-int
-ffs_mount(mp, path, data, ndp, p)
- register struct mount *mp;
- char *path;
- caddr_t data;
- struct nameidata *ndp;
- struct proc *p;
-{
- struct vnode *devvp;
- struct ufs_args args;
- struct ufsmount *ump = 0;
- register struct fs *fs;
- u_int size;
- int error, flags;
+ /*
+ ***
+ * Mounting non-root file system or updating a file system
+ ***
+ */
+
+ /* copy in user arguments*/
+ err = copyin(data, (caddr_t)&args, sizeof (struct ufs_args));
+ if (err)
+ goto error_1; /* can't get arguments*/
- error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args));
- if (error)
- return (error);
/*
* If updating, check whether changing from read-only to
* read/write; if there is no device name, that's all we do.
@@ -173,20 +191,23 @@ ffs_mount(mp, path, data, ndp, p)
if (mp->mnt_flag & MNT_UPDATE) {
ump = VFSTOUFS(mp);
fs = ump->um_fs;
- error = 0;
+ err = 0;
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 && (mp->mnt_flag & MNT_RELOAD))
- error = ffs_reload(mp, ndp->ni_cnd.cn_cred, p);
- if (error)
- return (error);
+ if (!err && (mp->mnt_flag & MNT_RELOAD))
+ err = ffs_reload(mp, ndp->ni_cnd.cn_cred, p);
+ if (err) {
+ goto error_1;
+ }
if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
if (!fs->fs_clean) {
if (mp->mnt_flag & MNT_FORCE) {
@@ -194,7 +215,8 @@ ffs_mount(mp, path, data, ndp, p)
} else {
printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n",
fs->fs_fsmnt);
- return (EPERM);
+ err = EPERM;
+ goto error_1;
}
}
fs->fs_ronly = 0;
@@ -203,56 +225,117 @@ ffs_mount(mp, path, data, ndp, p)
fs->fs_clean = 0;
ffs_sbupdate(ump, MNT_WAIT);
}
+ /* if not updating name...*/
if (args.fspec == 0) {
/*
- * Process export requests.
+ * Process export requests. Jumping to "success"
+ * will return the vfs_export() error code.
*/
- return (vfs_export(mp, &ump->um_export, &args.export));
+ err = vfs_export(mp, &ump->um_export, &args.export);
+ goto success;
}
}
+
/*
* Not an update, or updating the name: look up the name
* and verify that it refers to a sensible block device.
*/
NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
- error = namei(ndp);
- if (error)
- return (error);
+ err = namei(ndp);
+ if (err) {
+ /* can't get devvp!*/
+ goto error_1;
+ }
+
devvp = ndp->ni_vp;
if (devvp->v_type != VBLK) {
- vrele(devvp);
- return (ENOTBLK);
+ err = ENOTBLK;
+ goto error_2;
}
if (major(devvp->v_rdev) >= nblkdev) {
- vrele(devvp);
- return (ENXIO);
+ err = ENXIO;
+ goto error_2;
}
- if ((mp->mnt_flag & MNT_UPDATE) == 0)
- error = ffs_mountfs(devvp, mp, p);
- else {
+ if (mp->mnt_flag & MNT_UPDATE) {
+ /*
+ ********************
+ * UPDATE
+ ********************
+ */
+
if (devvp != ump->um_devvp)
- error = EINVAL; /* needs translation */
+ err = EINVAL; /* needs translation */
else
vrele(devvp);
+ /*
+ * Update device name only on success
+ */
+ if( !err) {
+ /* Save "mounted from" info for mount point (NULL pad)*/
+ copyinstr( args.fspec,
+ mp->mnt_stat.f_mntfromname,
+ MNAMELEN - 1,
+ &size);
+ bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+ }
+ } else {
+ /*
+ ********************
+ * NEW MOUNT
+ ********************
+ */
+
+ /*
+ * 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);
+
+ err = ffs_mountfs(devvp, mp, p);
}
- if (error) {
- vrele(devvp);
- return (error);
+ if (err) {
+ 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)ffs_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);
}
+
/*
* Reload all incore data for a filesystem (used after running fsck on
* the root filesystem and finding things to fix). The filesystem must
@@ -267,8 +350,8 @@ ffs_mount(mp, path, data, ndp, p)
* 6) re-read inode data for all active vnodes.
*/
int
-ffs_reload(mountp, cred, p)
- register struct mount *mountp;
+ffs_reload(mp, cred, p)
+ register struct mount *mp;
struct ucred *cred;
struct proc *p;
{
@@ -279,12 +362,12 @@ ffs_reload(mountp, cred, p)
struct fs *fs;
int i, blks, size, error;
- if ((mountp->mnt_flag & MNT_RDONLY) == 0)
+ if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EINVAL);
/*
* Step 1: invalidate all cached meta-data.
*/
- devvp = VFSTOUFS(mountp)->um_devvp;
+ devvp = VFSTOUFS(mp)->um_devvp;
if (vinvalbuf(devvp, 0, cred, p, 0, 0))
panic("ffs_reload: dirty1");
/*
@@ -299,7 +382,7 @@ ffs_reload(mountp, cred, p)
brelse(bp);
return (EIO); /* XXX needs translation */
}
- fs = VFSTOUFS(mountp)->um_fs;
+ fs = VFSTOUFS(mp)->um_fs;
bcopy(&fs->fs_csp[0], &((struct fs *)bp->b_data)->fs_csp[0],
sizeof(fs->fs_csp));
bcopy(bp->b_data, fs, (u_int)fs->fs_sbsize);
@@ -325,7 +408,7 @@ ffs_reload(mountp, cred, p)
brelse(bp);
}
loop:
- for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
+ for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
nvp = vp->v_mntvnodes.le_next;
/*
* Step 4: invalidate all inactive vnodes.
@@ -356,7 +439,7 @@ loop:
ino_to_fsbo(fs, ip->i_number));
brelse(bp);
vput(vp);
- if (vp->v_mount != mountp)
+ if (vp->v_mount != mp)
goto loop;
}
return (0);
@@ -380,6 +463,7 @@ ffs_mountfs(devvp, mp, p)
int havepart = 0, blks;
int error, i, size;
int ronly;
+ u_int strsize;
/*
* Disallow multiple mounts of the same device.
@@ -477,6 +561,24 @@ ffs_mountfs(devvp, mp, p)
devvp->v_specflags |= SI_MOUNTEDON;
ffs_oldfscompat(fs);
ffs_vmlimits(fs);
+
+ /*
+ * Set FS local "last mounted on" information (NULL pad)
+ */
+ copystr( mp->mnt_stat.f_mntonname, /* mount point*/
+ fs->fs_fsmnt, /* copy area*/
+ sizeof(fs->fs_fsmnt) - 1, /* max size*/
+ &strsize); /* real size*/
+ bzero( fs->fs_fsmnt + strsize, sizeof(fs->fs_fsmnt) - strsize);
+
+ if( mp->mnt_flag & MNT_ROOTFS) {
+ /*
+ * Root mount; update timestamp in mount structure.
+ * this will be used by the common root mount code
+ * to update the system clock.
+ */
+ mp->mnt_time = fs->fs_time;
+ }
if (ronly == 0)
ffs_sbupdate(ump, MNT_WAIT);
return (0);
diff --git a/sys/ufs/lfs/lfs_vfsops.c b/sys/ufs/lfs/lfs_vfsops.c
index e571dcd..80fb731 100644
--- a/sys/ufs/lfs/lfs_vfsops.c
+++ b/sys/ufs/lfs/lfs_vfsops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)lfs_vfsops.c 8.7 (Berkeley) 4/16/94
- * $Id: lfs_vfsops.c,v 1.10 1995/03/16 18:16:48 bde Exp $
+ * $Id: lfs_vfsops.c,v 1.11 1995/03/19 14:29:20 davidg Exp $
*/
#include <sys/param.h>
@@ -78,16 +78,45 @@ struct vfsops lfs_vfsops = {
VFS_SET(lfs_vfsops, lfs, MOUNT_LFS, 0);
-int
-lfs_mountroot()
-{
- panic("lfs_mountroot"); /* XXX -- implement */
-}
/*
- * VFS Operations.
+ * lfs_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)
+ *
+ * RETURNS: 0 Success
+ * !0 error number (errno.h)
+ *
+ * LOCK STATE:
*
- * mount system call
+ * 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.
+ *
+ * Root mounts are not currently supported.
*/
int
lfs_mount(mp, path, data, ndp, p)
@@ -102,14 +131,37 @@ lfs_mount(mp, path, data, ndp, p)
struct ufsmount *ump = 0;
register struct lfs *fs; /* LFS */
u_int size;
- int error;
+ int err;
- if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)))
- return (error);
+ /*
+ * Use NULL path to flag a root mount
+ */
+ if( path == NULL) {
+ /*
+ ***
+ * Mounting root file system
+ ***
+ */
+
+ /* XXX -- implement*/
+ panic("lfs_mountroot: can't setup bdevvp for root");
+ }
+
+ /*
+ ***
+ * Mounting non-root file system or updating a file system
+ ***
+ */
+
+ /* copy in user arguments*/
+ if (err = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)))
+ goto error_1;
/* Until LFS can do NFS right. XXX */
- if (args.export.ex_flags & MNT_EXPORTED)
- return (EINVAL);
+ if (args.export.ex_flags & MNT_EXPORTED) {
+ err = EINVAL;
+ goto error_1;
+ }
/*
* If updating, check whether changing from read-only to
@@ -128,9 +180,11 @@ lfs_mount(mp, path, data, ndp, p)
#endif
if (args.fspec == 0) {
/*
- * Process export requests.
+ * Process export requests. Jumping to "success"
+ * will return the vfs_export() error code.
*/
- return (vfs_export(mp, &ump->um_export, &args.export));
+ err = vfs_export(mp, &ump->um_export, &args.export);
+ goto success;
}
}
/*
@@ -138,28 +192,27 @@ lfs_mount(mp, path, data, ndp, p)
* and verify that it refers to a sensible block device.
*/
NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
- if (error = namei(ndp))
- return (error);
+ if (err = namei(ndp))
+ goto error_1;
devvp = ndp->ni_vp;
if (devvp->v_type != VBLK) {
- vrele(devvp);
- return (ENOTBLK);
+ err = ENOTBLK;
+ goto error_2;
}
if (major(devvp->v_rdev) >= nblkdev) {
- vrele(devvp);
- return (ENXIO);
+ err = ENXIO;
+ goto error_2;
}
if ((mp->mnt_flag & MNT_UPDATE) == 0)
- error = lfs_mountfs(devvp, mp, p); /* LFS */
+ err = lfs_mountfs(devvp, mp, p); /* LFS */
else {
if (devvp != ump->um_devvp)
- error = EINVAL; /* needs translation */
+ err = EINVAL; /* needs translation */
else
vrele(devvp);
}
- if (error) {
- vrele(devvp);
- return (error);
+ if (err) {
+ goto error_2;
}
ump = VFSTOUFS(mp);
fs = ump->um_lfs; /* LFS */
@@ -182,7 +235,18 @@ lfs_mount(mp, path, data, ndp, p)
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
(void) lfs_statfs(mp, &mp->mnt_stat, p);
#endif
- return (0);
+
+
+
+error_2: /* error with devvp held*/
+
+ /* release devvp before failing*/
+ vrele(devvp);
+
+error_1: /* no state to back out*/
+
+success:
+ return( err);
}
/*
diff --git a/sys/ufs/mfs/mfs_extern.h b/sys/ufs/mfs/mfs_extern.h
index fa51177..887c3d7 100644
--- a/sys/ufs/mfs/mfs_extern.h
+++ b/sys/ufs/mfs/mfs_extern.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)mfs_extern.h 8.1 (Berkeley) 6/11/93
- * $Id: mfs_extern.h,v 1.2 1994/08/02 07:54:42 davidg Exp $
+ * $Id: mfs_extern.h,v 1.3 1994/08/21 07:16:10 paul Exp $
*/
#ifndef _UFS_MFS_MFS_EXTERN_H_
@@ -56,6 +56,8 @@ int mfs_init __P((void));
int mfs_ioctl __P((struct vop_ioctl_args *));
int mfs_mount __P((struct mount *mp,
char *path, caddr_t data, struct nameidata *ndp, struct proc *p));
+int mfs_mountfs __P((struct vnode *, struct mount *, struct proc *));
+int mfs_mountroot __P((void));
int mfs_open __P((struct vop_open_args *));
int mfs_print __P((struct vop_print_args *)); /* XXX */
int mfs_start __P((struct mount *mp, int flags, struct proc *p));
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 */
/*
diff --git a/sys/ufs/ufs/dir.h b/sys/ufs/ufs/dir.h
index f18eca8..3eae47a 100644
--- a/sys/ufs/ufs/dir.h
+++ b/sys/ufs/ufs/dir.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)dir.h 8.2 (Berkeley) 1/21/94
- * $Id: dir.h,v 1.2 1994/08/02 07:54:48 davidg Exp $
+ * $Id: dir.h,v 1.3 1994/08/21 07:16:14 paul Exp $
*/
#ifndef _UFS_UFS_DIR_H_
@@ -101,15 +101,18 @@ struct direct {
* the directory entry. This requires the amount of space in struct direct
* without the d_name field, plus enough space for the name with a terminating
* null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
+ *
+ *
*/
+#define DIRECTSIZ(namlen) \
+ (((int)&((struct direct *)0)->d_name + \
+ ((namlen)+1)*sizeof(((struct direct *)0)->d_name[0]) + 3) & ~3)
#if (BYTE_ORDER == LITTLE_ENDIAN)
#define DIRSIZ(oldfmt, dp) \
- ((oldfmt) ? \
- ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_type+1 + 3) &~ 3)) : \
- ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)))
+ ((oldfmt) ? DIRECTSIZ((dp)->d_type) : DIRECTSIZ((dp)->d_namlen))
#else
#define DIRSIZ(oldfmt, dp) \
- ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+ DIRECTSIZ((dp)->d_namlen)
#endif
#define OLDDIRFMT 1
#define NEWDIRFMT 0
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index 2994c5c..045de4b 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_lookup.c 8.6 (Berkeley) 4/1/94
- * $Id: ufs_lookup.c,v 1.3 1994/10/08 06:57:26 phk Exp $
+ * $Id: ufs_lookup.c,v 1.4 1995/07/29 11:43:23 bde Exp $
*/
#include <sys/param.h>
@@ -59,7 +59,8 @@ int dirchk = 1;
int dirchk = 0;
#endif
-#define FSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0)
+/* true if old FS format...*/
+#define OFSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0)
/*
* Convert a component of a pathname into a pointer to a locked inode.
@@ -210,8 +211,7 @@ ufs_lookup(ap)
if ((nameiop == CREATE || nameiop == RENAME) &&
(flags & ISLASTCN)) {
slotstatus = NONE;
- slotneeded = (sizeof(struct direct) - MAXNAMLEN +
- cnp->cn_namelen + 3) &~ 3;
+ slotneeded = DIRECTSIZ(cnp->cn_namelen);
}
/*
@@ -295,7 +295,7 @@ searchloop:
int size = ep->d_reclen;
if (ep->d_ino != 0)
- size -= DIRSIZ(FSFMT(vdp), ep);
+ size -= DIRSIZ(OFSFMT(vdp), ep);
if (size > 0) {
if (size >= slotneeded) {
slotstatus = FOUND;
@@ -319,10 +319,10 @@ searchloop:
*/
if (ep->d_ino) {
# if (BYTE_ORDER == LITTLE_ENDIAN)
- if (vdp->v_mount->mnt_maxsymlinklen > 0)
- namlen = ep->d_namlen;
- else
+ if (OFSFMT(vdp))
namlen = ep->d_type;
+ else
+ namlen = ep->d_namlen;
# else
namlen = ep->d_namlen;
# endif
@@ -426,9 +426,9 @@ found:
* Check that directory length properly reflects presence
* of this entry.
*/
- if (entryoffsetinblock + DIRSIZ(FSFMT(vdp), ep) > dp->i_size) {
+ if (entryoffsetinblock + DIRSIZ(OFSFMT(vdp), ep) > dp->i_size) {
ufs_dirbad(dp, dp->i_offset, "i_size too small");
- dp->i_size = entryoffsetinblock + DIRSIZ(FSFMT(vdp), ep);
+ dp->i_size = entryoffsetinblock + DIRSIZ(OFSFMT(vdp), ep);
dp->i_flag |= IN_CHANGE | IN_UPDATE;
}
@@ -604,16 +604,16 @@ ufs_dirbadentry(dp, ep, entryoffsetinblock)
int namlen;
# if (BYTE_ORDER == LITTLE_ENDIAN)
- if (dp->v_mount->mnt_maxsymlinklen > 0)
- namlen = ep->d_namlen;
- else
+ if (OFSFMT(dp))
namlen = ep->d_type;
+ else
+ namlen = ep->d_namlen;
# else
namlen = ep->d_namlen;
# endif
if ((ep->d_reclen & 0x3) != 0 ||
ep->d_reclen > DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1)) ||
- ep->d_reclen < DIRSIZ(FSFMT(dp), ep) || namlen > MAXNAMLEN) {
+ ep->d_reclen < DIRSIZ(OFSFMT(dp), ep) || namlen > MAXNAMLEN) {
/*return (1); */
printf("First bad\n");
goto bad;
@@ -663,7 +663,7 @@ ufs_direnter(ip, dvp, cnp)
newdir.d_ino = ip->i_number;
newdir.d_namlen = cnp->cn_namelen;
bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
- if (dvp->v_mount->mnt_maxsymlinklen > 0)
+ if (!OFSFMT(dvp))
newdir.d_type = IFTODT(ip->i_mode);
else {
newdir.d_type = 0;
@@ -673,7 +673,7 @@ ufs_direnter(ip, dvp, cnp)
newdir.d_type = tmp; }
# endif
}
- newentrysize = DIRSIZ(FSFMT(dvp), &newdir);
+ newentrysize = DIRSIZ(OFSFMT(dvp), &newdir);
if (dp->i_count == 0) {
/*
* If dp->i_count is 0, then namei could find no
@@ -737,7 +737,7 @@ ufs_direnter(ip, dvp, cnp)
* space.
*/
ep = (struct direct *)dirbuf;
- dsize = DIRSIZ(FSFMT(dvp), ep);
+ dsize = DIRSIZ(OFSFMT(dvp), ep);
spacefree = ep->d_reclen - dsize;
for (loc = ep->d_reclen; loc < dp->i_count; ) {
nep = (struct direct *)(dirbuf + loc);
@@ -749,7 +749,7 @@ ufs_direnter(ip, dvp, cnp)
/* overwrite; nothing there; header is ours */
spacefree += dsize;
}
- dsize = DIRSIZ(FSFMT(dvp), nep);
+ dsize = DIRSIZ(OFSFMT(dvp), nep);
spacefree += nep->d_reclen - dsize;
loc += nep->d_reclen;
bcopy((caddr_t)nep, (caddr_t)ep, dsize);
@@ -846,7 +846,7 @@ ufs_dirrewrite(dp, ip, cnp)
if (error)
return (error);
ep->d_ino = ip->i_number;
- if (vdp->v_mount->mnt_maxsymlinklen > 0)
+ if (!OFSFMT(vdp))
ep->d_type = IFTODT(ip->i_mode);
error = VOP_BWRITE(bp);
dp->i_flag |= IN_CHANGE | IN_UPDATE;
@@ -891,10 +891,10 @@ ufs_dirempty(ip, parentino, cred)
continue;
/* accept only "." and ".." */
# if (BYTE_ORDER == LITTLE_ENDIAN)
- if (ITOV(ip)->v_mount->mnt_maxsymlinklen > 0)
- namlen = dp->d_namlen;
- else
+ if (OFSFMT(ITOV(ip)))
namlen = dp->d_type;
+ else
+ namlen = dp->d_namlen;
# else
namlen = dp->d_namlen;
# endif
@@ -951,10 +951,10 @@ ufs_checkpath(source, target, cred)
if (error != 0)
break;
# if (BYTE_ORDER == LITTLE_ENDIAN)
- if (vp->v_mount->mnt_maxsymlinklen > 0)
- namlen = dirbuf.dotdot_namlen;
- else
+ if (OFSFMT(vp))
namlen = dirbuf.dotdot_type;
+ else
+ namlen = dirbuf.dotdot_namlen;
# else
namlen = dirbuf.dotdot_namlen;
# endif
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 37000cc..371cd06 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_vnops.c 8.10 (Berkeley) 4/1/94
- * $Id: ufs_vnops.c,v 1.25 1995/06/28 07:06:55 davidg Exp $
+ * $Id: ufs_vnops.c,v 1.26 1995/08/01 18:51:02 davidg Exp $
*/
#include <sys/param.h>
@@ -1123,12 +1123,12 @@ out:
* A virgin directory (no blushing please).
*/
static struct dirtemplate mastertemplate = {
- 0, 12, DT_DIR, 1, ".",
- 0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
+ 0, 12, DT_DIR, 1, { '.', 0 },
+ 0, DIRBLKSIZ - 12, DT_DIR, 2, { '.', '.', 0 }
};
static struct odirtemplate omastertemplate = {
- 0, 12, 1, ".",
- 0, DIRBLKSIZ - 12, 2, ".."
+ 0, 12, 1, { '.', 0 },
+ 0, DIRBLKSIZ - 12, 2, { '.', '.', 0 }
};
/*
OpenPOWER on IntegriCloud