From c9ad8a67af1698112b3fd4b4e69926cce376dfd9 Mon Sep 17 00:00:00 2001 From: Kelly Yancey Date: Mon, 15 May 2006 19:42:10 +0000 Subject: [PATCH] Restore the ability to mount procfs and fdescfs filesystems via the mount(2) system call: * Add cmount hook to fdescfs and pseudofs (and, by extension, procfs and linprocfs). This (mostly) restores the ability to mount these filesystems using the old mount(2) system call (see below for the rest of the fix). * Remove not-NULL check for the data argument from the mount(2) entry point. Per the mount(2) man page, it is up to the individual filesystem being mounted to verify data. Or, in the case of procfs, etc. the filesystem is free to ignore the data parameter if it does not use it. Enforcing data to be not-NULL in the mount(2) system call entry point prevented passing NULL to filesystems which ignored the data pointer value. Apparently, passing NULL was common practice in such cases, as even our own mount_std(8) used to do it in the pre-nmount(2) world. All userland programs in the tree were converted to nmount(2) long ago, but I've found at least one external program which broke due to this (presumably unintentional) mount(2) API change. One could argue that external programs should also be converted to nmount(2), but then there isn't much point in keeping the mount(2) interface for backward compatibility if it isn't backward compatible. --- sys/fs/fdescfs/fdesc_vfsops.c | 11 +++++++++++ sys/fs/pseudofs/pseudofs.c | 9 +++++++++ sys/fs/pseudofs/pseudofs.h | 4 ++++ sys/kern/vfs_mount.c | 3 --- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/sys/fs/fdescfs/fdesc_vfsops.c b/sys/fs/fdescfs/fdesc_vfsops.c index c175d0a3093..6356147b420 100644 --- a/sys/fs/fdescfs/fdesc_vfsops.c +++ b/sys/fs/fdescfs/fdesc_vfsops.c @@ -54,11 +54,21 @@ static MALLOC_DEFINE(M_FDESCMNT, "fdesc_mount", "FDESC mount structure"); +static vfs_cmount_t fdesc_cmount; static vfs_mount_t fdesc_mount; static vfs_unmount_t fdesc_unmount; static vfs_statfs_t fdesc_statfs; static vfs_root_t fdesc_root; +/* + * Compatibility shim for old mount(2) system call. + */ +int +fdesc_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +{ + return kernel_mount(ma, flags); +} + /* * Mount the per-process file descriptors (/dev/fd) */ @@ -193,6 +203,7 @@ fdesc_statfs(mp, sbp, td) } static struct vfsops fdesc_vfsops = { + .vfs_cmount = fdesc_cmount, .vfs_init = fdesc_init, .vfs_mount = fdesc_mount, .vfs_root = fdesc_root, diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c index 1fe0371711e..da1758b9303 100644 --- a/sys/fs/pseudofs/pseudofs.c +++ b/sys/fs/pseudofs/pseudofs.c @@ -284,6 +284,15 @@ pfs_mount(struct pfs_info *pi, struct mount *mp, struct thread *td) return (0); } +/* + * Compatibility shim for old mount(2) system call. + */ +int +pfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +{ + return kernel_mount(ma, flags); +} + /* * Unmount a pseudofs instance */ diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h index 8eaa13735d3..b9701bc0933 100644 --- a/sys/fs/pseudofs/pseudofs.h +++ b/sys/fs/pseudofs/pseudofs.h @@ -34,6 +34,7 @@ /* * Opaque structures */ +struct mntarg; struct mount; struct nameidata; struct proc; @@ -199,6 +200,8 @@ struct pfs_node { */ int pfs_mount (struct pfs_info *pi, struct mount *mp, struct thread *td); +int pfs_cmount (struct mntarg *ma, void *data, int flags, + struct thread *td); int pfs_unmount (struct mount *mp, int mntflags, struct thread *td); int pfs_root (struct mount *mp, int flags, @@ -251,6 +254,7 @@ _##name##_uninit(struct vfsconf *vfc) { \ } \ \ static struct vfsops name##_vfsops = { \ + .vfs_cmount = pfs_cmount, \ .vfs_init = _##name##_init, \ .vfs_mount = _##name##_mount, \ .vfs_root = pfs_root, \ diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 1d1cc6cea73..2f609425886 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -736,9 +736,6 @@ mount(td, uap) /* Kick out MNT_ROOTFS early as it is legal internally */ uap->flags &= ~MNT_ROOTFS; - if (uap->data == NULL) - return (EINVAL); - fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK); error = copyinstr(uap->type, fstype, MFSNAMELEN, NULL); if (!error) {