summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-12-07 08:15:41 +0000
committerphk <phk@FreeBSD.org>2004-12-07 08:15:41 +0000
commit4a639d6164f667049cce0046d22e760ca1aad3f2 (patch)
tree8a677b8e6580c00ab014aebc4c8dc33107ab26f3 /sys/ufs
parentb183fa653bf444f02ca3966a2ba789e50318ee0c (diff)
downloadFreeBSD-src-4a639d6164f667049cce0046d22e760ca1aad3f2.zip
FreeBSD-src-4a639d6164f667049cce0046d22e760ca1aad3f2.tar.gz
The remaining part of nmount/omount/rootfs mount changes. I cannot sensibly
split the conversion of the remaining three filesystems out from the root mounting changes, so in one go: cd9660: Convert to nmount. Add omount compat shims. Remove dedicated rootfs mounting code. Use vfs_mountedfrom() Rely on vfs_mount.c calling VFS_STATFS() nfs(client): Convert to nmount (the simple way, mount_nfs(8) is still necessary). Add omount compat shims. Drop COMPAT_PRELITE2 mount arg compatibility. ffs: Convert to nmount. Add omount compat shims. Remove dedicated rootfs mounting code. Use vfs_mountedfrom() Rely on vfs_mount.c calling VFS_STATFS() Remove vfs_omount() method, all filesystems are now converted. Remove MNTK_WANTRDWR, handling RO/RW conversions is a filesystem task, and they all do it now. Change rootmounting to use DEVFS trampoline: vfs_mount.c: Mount devfs on /. Devfs needs no 'from' so this is clean. symlink /dev to /. This makes it possible to lookup /dev/foo. Mount "real" root filesystem on /. Surgically move the devfs mountpoint from under the real root filesystem onto /dev in the real root filesystem. Remove now unnecessary getdiskbyname(). kern_init.c: Don't do devfs mounting and rootvnode assignment here, it was already handled by vfs_mount.c. Remove now unused bdevvp(), addaliasu() and addalias(). Put the few necessary lines in devfs where they belong. This eliminates the second-last source of bogo vnodes, leaving only the lemming-syncer. Remove rootdev variable, it doesn't give meaning in a global context and was not trustworth anyway. Correct information is provided by statfs(/).
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c151
1 files changed, 57 insertions, 94 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 341179f..7b9f4d5 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -81,13 +81,15 @@ static void ffs_ifree(struct ufsmount *ump, struct inode *ip);
static vfs_init_t ffs_init;
static vfs_uninit_t ffs_uninit;
static vfs_extattrctl_t ffs_extattrctl;
-static vfs_omount_t ffs_omount;
+static vfs_cmount_t ffs_cmount;
+static vfs_mount_t ffs_mount;
static struct vfsops ufs_vfsops = {
.vfs_extattrctl = ffs_extattrctl,
.vfs_fhtovp = ffs_fhtovp,
.vfs_init = ffs_init,
- .vfs_omount = ffs_omount,
+ .vfs_mount = ffs_mount,
+ .vfs_cmount = ffs_cmount,
.vfs_quotactl = ufs_quotactl,
.vfs_root = ufs_root,
.vfs_statfs = ffs_statfs,
@@ -108,55 +110,23 @@ static struct buf_ops ffs_ops = {
.bop_strategy = ffs_geom_strategy,
};
-/*
- * ffs_omount
- *
- * Called when mounting local physical media
- *
- * PARAMETERS:
- * mountroot
- * mp mount point structure
- * path path to mount point
- * 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
- *
- * 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.
- */
+static const char *ffs_opts[] = { "from", "export", NULL };
+
static int
-ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
+ffs_mount(struct mount *mp, struct thread *td)
{
- size_t size;
- struct vnode *devvp, *rootvp;
- struct ufs_args args;
+ struct vnode *devvp;
struct ufsmount *ump = 0;
struct fs *fs;
int error, flags;
mode_t accessmode;
struct nameidata ndp;
+ struct export_args *export;
+ char *fspec;
+ int len;
+ if (vfs_filteropt(mp->mnt_optnew, ffs_opts))
+ return (EINVAL);
if (uma_inode == NULL) {
uma_inode = uma_zcreate("FFS inode",
sizeof(struct inode), NULL, NULL, NULL, NULL,
@@ -168,27 +138,10 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
sizeof(struct ufs2_dinode), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, 0);
}
- if ((mp->mnt_flag & MNT_ROOTFS) && mp->mnt_data == NULL) {
- if ((error = bdevvp(rootdev, &rootvp))) {
- printf("ffs_mountroot: can't find rootvp\n");
- return (error);
- }
-
- if ((error = ffs_mountfs(rootvp, mp, td)) != 0)
- return (error);
- return (0);
- }
- /*
- * Get mount options, if any.
- */
- if (data != NULL) {
- error = copyin(data, (caddr_t)&args, sizeof args);
- if (error)
- return (error);
- } else {
- memset(&args, 0, sizeof args);
- }
+ fspec = vfs_getopts(mp->mnt_optnew, "from", &error);
+ if (error)
+ return (error);
/*
* If updating, check whether changing from read-only to
@@ -198,7 +151,8 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
ump = VFSTOUFS(mp);
fs = ump->um_fs;
devvp = ump->um_devvp;
- if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
+ if (fs->fs_ronly == 0 &&
+ vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) {
if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
return (error);
/*
@@ -234,7 +188,6 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
fs->fs_pendingblocks = 0;
fs->fs_pendinginodes = 0;
}
- fs->fs_ronly = 1;
if ((fs->fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) == 0)
fs->fs_clean = 1;
if ((error = ffs_sbupdate(ump, MNT_WAIT)) != 0) {
@@ -249,11 +202,14 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
g_access(ump->um_cp, 0, -1, 0);
g_topology_unlock();
PICKUP_GIANT();
+ fs->fs_ronly = 1;
+ mp->mnt_flag |= MNT_RDONLY;
}
if ((mp->mnt_flag & MNT_RELOAD) &&
(error = ffs_reload(mp, td)) != 0)
return (error);
- if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
+ if (fs->fs_ronly &&
+ !vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) {
/*
* If upgrade to read-write by non-root, then verify
* that user has necessary permissions on the device.
@@ -299,6 +255,7 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
return (error);
fs->fs_ronly = 0;
+ mp->mnt_flag &= ~MNT_RDONLY;
fs->fs_clean = 0;
if ((error = ffs_sbupdate(ump, MNT_WAIT)) != 0) {
vn_finished_write(mp);
@@ -326,20 +283,25 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
/*
* If not updating name, process export requests.
*/
- if (args.fspec == 0)
- return (vfs_export(mp, &args.export));
+ if (fspec == NULL) {
+ error = vfs_getopt(mp->mnt_optnew,
+ "export", (void **)&export, &len);
+ if (error || len != sizeof *export)
+ return (EINVAL);
+ return (vfs_export(mp, export));
+ }
/*
* If this is a snapshot request, take the snapshot.
*/
if (mp->mnt_flag & MNT_SNAPSHOT)
- return (ffs_snapshot(mp, args.fspec));
+ return (ffs_snapshot(mp, fspec));
}
/*
* Not an update, or updating the name: look up the name
* and verify that it refers to a sensible disk device.
*/
- NDINIT(&ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, td);
+ NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fspec, td);
if ((error = namei(&ndp)) != 0)
return (error);
NDFREE(&ndp, NDF_ONLY_PNBUF);
@@ -392,15 +354,34 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
return (error);
}
}
- /*
- * Save "mounted from" device name 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);
+ vfs_mountedfrom(mp, fspec);
return (0);
}
/*
+ * Compatibility with old mount system call.
+ */
+
+static int
+ffs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
+{
+ struct ufs_args args;
+ int error;
+
+ if (data == NULL)
+ return (EINVAL);
+ error = copyin(data, &args, sizeof args);
+ if (error)
+ return (error);
+
+ ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
+ ma = mount_arg(ma, "export", &args.export, sizeof args.export);
+ error = kernel_mount(ma, flags);
+
+ return (error);
+}
+
+/*
* Reload all incore data for a filesystem (used after running fsck on
* the root filesystem and finding things to fix). The filesystem must
* be mounted read-only.
@@ -572,7 +553,6 @@ ffs_mountfs(devvp, mp, td)
int error, i, blks, size, ronly;
int32_t *lp;
struct ucred *cred;
- size_t strsize;
struct g_consumer *cp;
dev = devvp->v_rdev;
@@ -580,18 +560,6 @@ ffs_mountfs(devvp, mp, td)
vfs_object_create(devvp, td, td->td_ucred);
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
-#if 0
- /*
- * XXX: check filesystem permissions, they may be more strict
- * XXX: than what geom enforces.
- * XXX: But since we're root, they wouldn't matter, would they ?
- */
- error = VOP_ACCESS(devvp, ronly ? FREAD : FREAD | FWRITE, FSCRED, td);
- if (error) {
- VOP_UNLOCK(devvp, 0, td);
- return (error);
- }
-#endif
DROP_GIANT();
g_topology_lock();
error = g_vfs_open(devvp, &cp, "ffs", ronly ? 0 : 1);
@@ -770,11 +738,7 @@ ffs_mountfs(devvp, mp, td)
/*
* 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);
+ vfs_mountedfrom(mp, fs->fs_fsmnt);
if( mp->mnt_flag & MNT_ROOTFS) {
/*
@@ -800,7 +764,6 @@ ffs_mountfs(devvp, mp, td)
/*
* Initialize filesystem stat information in mount struct.
*/
- (void)VFS_STATFS(mp, &mp->mnt_stat, td);
#ifdef UFS_EXTATTR
#ifdef UFS_EXTATTR_AUTOSTART
/*
OpenPOWER on IntegriCloud