Reviewed by: jlemon

An initial tidyup of the mount() syscall and VFS mount code.

This code replaces the earlier work done by jlemon in an attempt to
make linux_mount() work.

* the guts of the mount work has been moved into vfs_mount().

* move `type', `path' and `flags' from being userland variables into being
  kernel variables in vfs_mount(). `data' remains a pointer into
  userspace.

* Attempt to verify the `type' and `path' strings passed to vfs_mount()
  aren't too long.

* rework mount() and linux_mount() to take the userland parameters
  (besides data, as mentioned) and pass kernel variables to vfs_mount().
  (linux_mount() already did this, I've just tidied it up a little more.)

* remove the copyin*() stuff for `path'. `data' still requires copyin*()
  since its a pointer into userland.

* set `mount->mnt_statf_mntonname' in vfs_mount() rather than in each
  filesystem.  This variable is generally initialised with `path', and
  each filesystem can override it if they want to.

* NOTE: f_mntonname is intiailised with "/" in the case of a root mount.
This commit is contained in:
Adrian Chadd 2001-03-01 21:00:17 +00:00
parent c909b97167
commit f3a90da995
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=73286
32 changed files with 209 additions and 175 deletions

View File

@ -90,9 +90,6 @@ linprocfs_mount(mp, path, data, ndp, p)
mp->mnt_data = 0;
vfs_getnewfsid(mp);
(void) copyinstr(path, (caddr_t)mp->mnt_stat.f_mntonname, MNAMELEN, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
size = sizeof("linprocfs") - 1;
bcopy("linprocfs", mp->mnt_stat.f_mntfromname, size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -901,14 +901,16 @@ linux_pwrite(p, uap)
int
linux_mount(struct proc *p, struct linux_mount_args *args)
{
struct mount_args bsd_args;
struct ufs_args ufs;
char fstypename[MFSNAMELEN];
char mntonname[MNAMELEN], mntfromname[MNAMELEN];
int error = 0;
int error;
int fsflags;
const char *fstype;
void *fsdata;
error = copyinstr(args->filesystemtype, fstypename,
MFSNAMELEN - 1, NULL);
error = copyinstr(args->filesystemtype, fstypename, MFSNAMELEN - 1,
NULL);
if (error)
return (error);
error = copyinstr(args->specialfile, mntfromname, MFSNAMELEN - 1, NULL);
@ -925,22 +927,21 @@ linux_mount(struct proc *p, struct linux_mount_args *args)
#endif
if (strcmp(fstypename, "ext2") == 0) {
bsd_args.type = "ext2fs";
bsd_args.data = (void *)&ufs;
fstype = "ext2fs";
fsdata = &ufs;
ufs.fspec = mntfromname;
#define DEFAULT_ROOTID -2
ufs.export.ex_root = DEFAULT_ROOTID;
ufs.export.ex_flags =
args->rwflag & LINUX_MS_RDONLY ? MNT_EXRDONLY : 0;
} else if (strcmp(fstypename, "proc") == 0) {
bsd_args.type = "linprocfs";
bsd_args.data = NULL;
fstype = "linprocfs";
fsdata = NULL;
} else {
return (ENODEV);
}
bsd_args.path = mntonname;
bsd_args.flags = 0;
fsflags = 0;
if ((args->rwflag & 0xffff0000) == 0xc0ed0000) {
/*
@ -948,18 +949,18 @@ linux_mount(struct proc *p, struct linux_mount_args *args)
* FreeBSD has is !ASYNC, which is our default.
*/
if (args->rwflag & LINUX_MS_RDONLY)
bsd_args.flags |= MNT_RDONLY;
fsflags |= MNT_RDONLY;
if (args->rwflag & LINUX_MS_NOSUID)
bsd_args.flags |= MNT_NOSUID;
fsflags |= MNT_NOSUID;
if (args->rwflag & LINUX_MS_NODEV)
bsd_args.flags |= MNT_NODEV;
fsflags |= MNT_NODEV;
if (args->rwflag & LINUX_MS_NOEXEC)
bsd_args.flags |= MNT_NOEXEC;
fsflags |= MNT_NOEXEC;
if (args->rwflag & LINUX_MS_REMOUNT)
bsd_args.flags |= MNT_UPDATE;
fsflags |= MNT_UPDATE;
}
return (mount1(p, &bsd_args, UIO_SYSSPACE));
return (vfs_mount(p, fstype, mntonname, fsflags, fsdata));
}
int

View File

@ -249,8 +249,6 @@ cd9660_mount(mp, path, data, ndp, p)
return error;
}
imp = VFSTOISOFS(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -67,7 +67,6 @@ devfs_mount(mp, path, data, ndp, p)
struct proc *p;
{
int error;
size_t size;
struct devfs_mount *fmp;
struct vnode *rvp;
@ -100,13 +99,6 @@ devfs_mount(mp, path, data, ndp, p)
}
VOP_UNLOCK(rvp, 0, p);
if (path != NULL) {
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
} else {
strcpy(mp->mnt_stat.f_mntonname, "/");
size = 1;
}
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
bcopy("devfs", mp->mnt_stat.f_mntfromname, sizeof("devfs"));
(void)devfs_statfs(mp, &mp->mnt_stat, p);

View File

@ -74,7 +74,6 @@ fdesc_mount(mp, path, data, ndp, p)
struct proc *p;
{
int error = 0;
u_int size;
struct fdescmount *fmp;
struct vnode *rvp;
@ -98,8 +97,6 @@ fdesc_mount(mp, path, data, ndp, p)
mp->mnt_data = (qaddr_t) fmp;
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc"));
(void)fdesc_statfs(mp, &mp->mnt_stat, p);

View File

@ -272,16 +272,12 @@ hpfs_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.
* error occurs, the mountpoint is discarded by the
* upper level code. Note that vfs_mount() handles
* copying the mountpoint f_mntonname for us, so we
* don't have to do it here unless we want to set it
* to something other than "path" for some rason.
*/
/* 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*/

View File

@ -345,9 +345,6 @@ msdosfs_mount(mp, path, data, ndp, p)
msdosfs_unmount(mp, MNT_FORCE, p);
return error;
}
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -376,16 +376,12 @@ ntfs_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.
* error occurs, the mountpoint is discarded by the
* upper level code. Note that vfs_mount() handles
* copying the mountpoint f_mntonname for us, so we
* don't have to do it here unless we want to set it
* to something other than "path" for some rason.
*/
/* 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*/

View File

@ -191,8 +191,6 @@ nullfs_mount(mp, path, data, ndp, p)
mp->mnt_data = (qaddr_t) xmp;
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -146,7 +146,6 @@ static int nwfs_mount(struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct proc *p)
{
struct nwfs_args args; /* will hold data from mount request */
size_t size;
int error;
struct nwmount *nmp = NULL;
struct ncp_conn *conn = NULL;
@ -198,8 +197,6 @@ static int nwfs_mount(struct mount *mp, char *path, caddr_t data,
nmp->m.dir_mode = (nmp->m.dir_mode &
(S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
if ((error = nwfs_initnls(nmp)) != 0) goto bad;
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
pc = mp->mnt_stat.f_mntfromname;
pe = pc+sizeof(mp->mnt_stat.f_mntfromname);
bzero(pc, MNAMELEN);

View File

@ -133,8 +133,6 @@ portal_mount(mp, path, data, ndp, p)
mp->mnt_data = (qaddr_t) fmp;
vfs_getnewfsid(mp);
(void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void)copyinstr(args.pa_config,
mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -221,8 +221,6 @@ umapfs_mount(mp, path, data, ndp, p)
mp->mnt_data = (qaddr_t) amp;
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -253,9 +253,6 @@ union_mount(mp, path, data, ndp, p)
mp->mnt_data = (qaddr_t) um;
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
switch (um->um_op) {
case UNMNT_ABOVE:
cp = "<above>:";

View File

@ -192,7 +192,11 @@ ext2_mount(mp, path, data, ndp, p)
int error, flags;
mode_t accessmode;
if ((error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) != 0)
/* Double-check the length of path.. */
if (strlen(path) >= MAXMNTLEN - 1)
return (ENAMETOOLONG);
error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args));
if (error != 0)
return (error);
/*
* If updating, check whether changing from read-only to
@ -308,10 +312,12 @@ ext2_mount(mp, path, data, ndp, p)
}
ump = VFSTOUFS(mp);
fs = ump->um_e2fs;
(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);
/*
* Note that this strncpy() is ok because of a check at the start
* of ext2_mount().
*/
strncpy(fs->fs_fsmnt, path, MAXMNTLEN);
fs->fs_fsmnt[MAXMNTLEN - 1] = '\0';
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -192,7 +192,11 @@ ext2_mount(mp, path, data, ndp, p)
int error, flags;
mode_t accessmode;
if ((error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) != 0)
/* Double-check the length of path.. */
if (strlen(path) >= MAXMNTLEN - 1)
return (ENAMETOOLONG);
error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args));
if (error != 0)
return (error);
/*
* If updating, check whether changing from read-only to
@ -308,10 +312,12 @@ ext2_mount(mp, path, data, ndp, p)
}
ump = VFSTOUFS(mp);
fs = ump->um_e2fs;
(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);
/*
* Note that this strncpy() is ok because of a check at the start
* of ext2_mount().
*/
strncpy(fs->fs_fsmnt, path, MAXMNTLEN);
fs->fs_fsmnt[MAXMNTLEN - 1] = '\0';
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -249,8 +249,6 @@ cd9660_mount(mp, path, data, ndp, p)
return error;
}
imp = VFSTOISOFS(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -214,6 +214,14 @@ vfs_mountroot_try(char *mountfrom)
(devsw(rootdev)->d_flags & D_MEMDISK))
mp->mnt_flag &= ~MNT_RDONLY;
/*
* Set the mount path to be something useful, because the
* filesystem code isn't responsible now for initialising
* f_mntonname unless they want to override the default
* (which is `path'.)
*/
strncpy(mp->mnt_stat.f_mntonname, "/", MNAMELEN);
error = VFS_MOUNT(mp, NULL, NULL, NULL, curproc);
done:

View File

@ -107,14 +107,6 @@ struct mount_args {
/* ARGSUSED */
int
mount(p, uap)
struct proc *p;
struct mount_args *uap;
{
return (mount1(p, uap, UIO_USERSPACE));
}
int
mount1(p, uap, segflag)
struct proc *p;
struct mount_args /* {
syscallarg(char *) type;
@ -122,7 +114,47 @@ mount1(p, uap, segflag)
syscallarg(int) flags;
syscallarg(caddr_t) data;
} */ *uap;
int segflag;
{
char *fstype;
char *fspath;
int error;
fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK | M_ZERO);
fspath = malloc(MNAMELEN, M_TEMP, M_WAITOK | M_ZERO);
/*
* vfs_mount() actually takes a kernel string for `type' and
* `path' now, so extract them.
*/
error = copyinstr(SCARG(uap, type), fstype, MFSNAMELEN, NULL);
if (error)
goto finish;
error = copyinstr(SCARG(uap, path), fspath, MNAMELEN, NULL);
if (error)
goto finish;
error = vfs_mount(p, fstype, fspath, SCARG(uap, flags),
SCARG(uap, data));
finish:
free(fstype, M_TEMP);
free(fspath, M_TEMP);
return (error);
}
/*
* vfs_mount(): actually attempt a filesystem mount.
*
* This routine is designed to be a "generic" entry point for routines
* that wish to mount a filesystem. All parameters except `fsdata' are
* pointers into kernel space. `fsdata' is currently still a pointer
* into userspace.
*/
int
vfs_mount(p, fstype, fspath, fsflags, fsdata)
struct proc *p;
char *fstype;
char *fspath;
int fsflags;
void *fsdata;
{
struct vnode *vp;
struct mount *mp;
@ -130,14 +162,22 @@ mount1(p, uap, segflag)
int error, flag = 0, flag2 = 0;
struct vattr va;
struct nameidata nd;
char fstypename[MFSNAMELEN];
/*
* Be ultra-paranoid about making sure the type and fspath
* variables will fit in our mp buffers, including the
* terminating NUL.
*/
if ((strlen(fstype) >= MNAMELEN - 1) ||
(strlen(fspath) >= MFSNAMELEN - 1))
return (ENAMETOOLONG);
if (usermount == 0 && (error = suser(p)))
return (error);
/*
* Do not allow NFS export by non-root users.
*/
if (SCARG(uap, flags) & MNT_EXPORTED) {
if (fsflags & MNT_EXPORTED) {
error = suser(p);
if (error)
return (error);
@ -146,16 +186,16 @@ mount1(p, uap, segflag)
* Silently enforce MNT_NOSUID and MNT_NODEV for non-root users
*/
if (suser_xxx(p->p_ucred, 0, 0))
SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
fsflags |= MNT_NOSUID | MNT_NODEV;
/*
* Get vnode to be covered
*/
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, segflag, SCARG(uap, path), p);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, p);
if ((error = namei(&nd)) != 0)
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
vp = nd.ni_vp;
if (SCARG(uap, flags) & MNT_UPDATE) {
if (fsflags & MNT_UPDATE) {
if ((vp->v_flag & VROOT) == 0) {
vput(vp);
return (EINVAL);
@ -167,7 +207,7 @@ mount1(p, uap, segflag)
* We only allow the filesystem to be reloaded if it
* is currently mounted read-only.
*/
if ((SCARG(uap, flags) & MNT_RELOAD) &&
if ((fsflags & MNT_RELOAD) &&
((mp->mnt_flag & MNT_RDONLY) == 0)) {
vput(vp);
return (EOPNOTSUPP); /* Needs translation */
@ -195,7 +235,7 @@ mount1(p, uap, segflag)
}
vp->v_flag |= VMOUNT;
mtx_unlock(&vp->v_interlock);
mp->mnt_flag |= SCARG(uap, flags) &
mp->mnt_flag |= fsflags &
(MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT);
VOP_UNLOCK(vp, 0, p);
goto update;
@ -218,13 +258,8 @@ mount1(p, uap, segflag)
vput(vp);
return (ENOTDIR);
}
if ((error = copyinstrfrom(SCARG(uap, type),
fstypename, MFSNAMELEN, NULL, segflag)) != 0) {
vput(vp);
return (error);
}
for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
if (!strcmp(vfsp->vfc_name, fstypename))
if (!strcmp(vfsp->vfc_name, fstype))
break;
if (vfsp == NULL) {
linker_file_t lf;
@ -234,7 +269,7 @@ mount1(p, uap, segflag)
vput(vp);
return error;
}
error = linker_load_file(fstypename, &lf);
error = linker_load_file(fstype, &lf);
if (error || lf == NULL) {
vput(vp);
if (lf == NULL)
@ -244,7 +279,7 @@ mount1(p, uap, segflag)
lf->userrefs++;
/* lookup again, see if the VFS was loaded */
for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
if (!strcmp(vfsp->vfc_name, fstypename))
if (!strcmp(vfsp->vfc_name, fstype))
break;
if (vfsp == NULL) {
lf->userrefs--;
@ -274,16 +309,19 @@ mount1(p, uap, segflag)
vfsp->vfc_refcount++;
mp->mnt_stat.f_type = vfsp->vfc_typenum;
mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
strncpy(mp->mnt_stat.f_fstypename, fstype, MFSNAMELEN);
mp->mnt_stat.f_fstypename[MFSNAMELEN - 1] = '\0';
mp->mnt_vnodecovered = vp;
mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
strncpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN);
mp->mnt_stat.f_mntonname[MNAMELEN - 1] = '\0';
mp->mnt_iosize_max = DFLTPHYS;
VOP_UNLOCK(vp, 0, p);
update:
/*
* Set the mount level flags.
*/
if (SCARG(uap, flags) & MNT_RDONLY)
if (fsflags & MNT_RDONLY)
mp->mnt_flag |= MNT_RDONLY;
else if (mp->mnt_flag & MNT_RDONLY)
mp->mnt_kern_flag |= MNTK_WANTRDWR;
@ -291,7 +329,7 @@ mount1(p, uap, segflag)
MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME |
MNT_NOSYMFOLLOW | MNT_IGNORE |
MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC |
mp->mnt_flag |= fsflags & (MNT_NOSUID | MNT_NOEXEC |
MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE |
MNT_NOSYMFOLLOW | MNT_IGNORE |
MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
@ -300,7 +338,7 @@ mount1(p, uap, segflag)
* XXX The final recipients of VFS_MOUNT just overwrite the ndp they
* get. No freeing of cn_pnbuf.
*/
error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, p);
error = VFS_MOUNT(mp, fspath, fsdata, &nd, p);
if (mp->mnt_flag & MNT_UPDATE) {
if (mp->mnt_kern_flag & MNTK_WANTRDWR)
mp->mnt_flag &= ~MNT_RDONLY;

View File

@ -214,6 +214,14 @@ vfs_mountroot_try(char *mountfrom)
(devsw(rootdev)->d_flags & D_MEMDISK))
mp->mnt_flag &= ~MNT_RDONLY;
/*
* Set the mount path to be something useful, because the
* filesystem code isn't responsible now for initialising
* f_mntonname unless they want to override the default
* (which is `path'.)
*/
strncpy(mp->mnt_stat.f_mntonname, "/", MNAMELEN);
error = VFS_MOUNT(mp, NULL, NULL, NULL, curproc);
done:

View File

@ -107,14 +107,6 @@ struct mount_args {
/* ARGSUSED */
int
mount(p, uap)
struct proc *p;
struct mount_args *uap;
{
return (mount1(p, uap, UIO_USERSPACE));
}
int
mount1(p, uap, segflag)
struct proc *p;
struct mount_args /* {
syscallarg(char *) type;
@ -122,7 +114,47 @@ mount1(p, uap, segflag)
syscallarg(int) flags;
syscallarg(caddr_t) data;
} */ *uap;
int segflag;
{
char *fstype;
char *fspath;
int error;
fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK | M_ZERO);
fspath = malloc(MNAMELEN, M_TEMP, M_WAITOK | M_ZERO);
/*
* vfs_mount() actually takes a kernel string for `type' and
* `path' now, so extract them.
*/
error = copyinstr(SCARG(uap, type), fstype, MFSNAMELEN, NULL);
if (error)
goto finish;
error = copyinstr(SCARG(uap, path), fspath, MNAMELEN, NULL);
if (error)
goto finish;
error = vfs_mount(p, fstype, fspath, SCARG(uap, flags),
SCARG(uap, data));
finish:
free(fstype, M_TEMP);
free(fspath, M_TEMP);
return (error);
}
/*
* vfs_mount(): actually attempt a filesystem mount.
*
* This routine is designed to be a "generic" entry point for routines
* that wish to mount a filesystem. All parameters except `fsdata' are
* pointers into kernel space. `fsdata' is currently still a pointer
* into userspace.
*/
int
vfs_mount(p, fstype, fspath, fsflags, fsdata)
struct proc *p;
char *fstype;
char *fspath;
int fsflags;
void *fsdata;
{
struct vnode *vp;
struct mount *mp;
@ -130,14 +162,22 @@ mount1(p, uap, segflag)
int error, flag = 0, flag2 = 0;
struct vattr va;
struct nameidata nd;
char fstypename[MFSNAMELEN];
/*
* Be ultra-paranoid about making sure the type and fspath
* variables will fit in our mp buffers, including the
* terminating NUL.
*/
if ((strlen(fstype) >= MNAMELEN - 1) ||
(strlen(fspath) >= MFSNAMELEN - 1))
return (ENAMETOOLONG);
if (usermount == 0 && (error = suser(p)))
return (error);
/*
* Do not allow NFS export by non-root users.
*/
if (SCARG(uap, flags) & MNT_EXPORTED) {
if (fsflags & MNT_EXPORTED) {
error = suser(p);
if (error)
return (error);
@ -146,16 +186,16 @@ mount1(p, uap, segflag)
* Silently enforce MNT_NOSUID and MNT_NODEV for non-root users
*/
if (suser_xxx(p->p_ucred, 0, 0))
SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
fsflags |= MNT_NOSUID | MNT_NODEV;
/*
* Get vnode to be covered
*/
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, segflag, SCARG(uap, path), p);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, p);
if ((error = namei(&nd)) != 0)
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
vp = nd.ni_vp;
if (SCARG(uap, flags) & MNT_UPDATE) {
if (fsflags & MNT_UPDATE) {
if ((vp->v_flag & VROOT) == 0) {
vput(vp);
return (EINVAL);
@ -167,7 +207,7 @@ mount1(p, uap, segflag)
* We only allow the filesystem to be reloaded if it
* is currently mounted read-only.
*/
if ((SCARG(uap, flags) & MNT_RELOAD) &&
if ((fsflags & MNT_RELOAD) &&
((mp->mnt_flag & MNT_RDONLY) == 0)) {
vput(vp);
return (EOPNOTSUPP); /* Needs translation */
@ -195,7 +235,7 @@ mount1(p, uap, segflag)
}
vp->v_flag |= VMOUNT;
mtx_unlock(&vp->v_interlock);
mp->mnt_flag |= SCARG(uap, flags) &
mp->mnt_flag |= fsflags &
(MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT);
VOP_UNLOCK(vp, 0, p);
goto update;
@ -218,13 +258,8 @@ mount1(p, uap, segflag)
vput(vp);
return (ENOTDIR);
}
if ((error = copyinstrfrom(SCARG(uap, type),
fstypename, MFSNAMELEN, NULL, segflag)) != 0) {
vput(vp);
return (error);
}
for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
if (!strcmp(vfsp->vfc_name, fstypename))
if (!strcmp(vfsp->vfc_name, fstype))
break;
if (vfsp == NULL) {
linker_file_t lf;
@ -234,7 +269,7 @@ mount1(p, uap, segflag)
vput(vp);
return error;
}
error = linker_load_file(fstypename, &lf);
error = linker_load_file(fstype, &lf);
if (error || lf == NULL) {
vput(vp);
if (lf == NULL)
@ -244,7 +279,7 @@ mount1(p, uap, segflag)
lf->userrefs++;
/* lookup again, see if the VFS was loaded */
for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
if (!strcmp(vfsp->vfc_name, fstypename))
if (!strcmp(vfsp->vfc_name, fstype))
break;
if (vfsp == NULL) {
lf->userrefs--;
@ -274,16 +309,19 @@ mount1(p, uap, segflag)
vfsp->vfc_refcount++;
mp->mnt_stat.f_type = vfsp->vfc_typenum;
mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
strncpy(mp->mnt_stat.f_fstypename, fstype, MFSNAMELEN);
mp->mnt_stat.f_fstypename[MFSNAMELEN - 1] = '\0';
mp->mnt_vnodecovered = vp;
mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
strncpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN);
mp->mnt_stat.f_mntonname[MNAMELEN - 1] = '\0';
mp->mnt_iosize_max = DFLTPHYS;
VOP_UNLOCK(vp, 0, p);
update:
/*
* Set the mount level flags.
*/
if (SCARG(uap, flags) & MNT_RDONLY)
if (fsflags & MNT_RDONLY)
mp->mnt_flag |= MNT_RDONLY;
else if (mp->mnt_flag & MNT_RDONLY)
mp->mnt_kern_flag |= MNTK_WANTRDWR;
@ -291,7 +329,7 @@ mount1(p, uap, segflag)
MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME |
MNT_NOSYMFOLLOW | MNT_IGNORE |
MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC |
mp->mnt_flag |= fsflags & (MNT_NOSUID | MNT_NOEXEC |
MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE |
MNT_NOSYMFOLLOW | MNT_IGNORE |
MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
@ -300,7 +338,7 @@ mount1(p, uap, segflag)
* XXX The final recipients of VFS_MOUNT just overwrite the ndp they
* get. No freeing of cn_pnbuf.
*/
error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, p);
error = VFS_MOUNT(mp, fspath, fsdata, &nd, p);
if (mp->mnt_flag & MNT_UPDATE) {
if (mp->mnt_kern_flag & MNTK_WANTRDWR)
mp->mnt_flag &= ~MNT_RDONLY;

View File

@ -74,7 +74,6 @@ fdesc_mount(mp, path, data, ndp, p)
struct proc *p;
{
int error = 0;
u_int size;
struct fdescmount *fmp;
struct vnode *rvp;
@ -98,8 +97,6 @@ fdesc_mount(mp, path, data, ndp, p)
mp->mnt_data = (qaddr_t) fmp;
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc"));
(void)fdesc_statfs(mp, &mp->mnt_stat, p);

View File

@ -191,8 +191,6 @@ nullfs_mount(mp, path, data, ndp, p)
mp->mnt_data = (qaddr_t) xmp;
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -133,8 +133,6 @@ portal_mount(mp, path, data, ndp, p)
mp->mnt_data = (qaddr_t) fmp;
vfs_getnewfsid(mp);
(void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void)copyinstr(args.pa_config,
mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -221,8 +221,6 @@ umapfs_mount(mp, path, data, ndp, p)
mp->mnt_data = (qaddr_t) amp;
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -253,9 +253,6 @@ union_mount(mp, path, data, ndp, p)
mp->mnt_data = (qaddr_t) um;
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
switch (um->um_op) {
case UNMNT_ABOVE:
cp = "<above>:";

View File

@ -345,9 +345,6 @@ msdosfs_mount(mp, path, data, ndp, p)
msdosfs_unmount(mp, MNT_FORCE, p);
return error;
}
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);

View File

@ -764,7 +764,7 @@ nfs_mount(mp, path, data, ndp, p)
struct nfs_args args;
struct sockaddr *nam;
struct vnode *vp;
char pth[MNAMELEN], hst[MNAMELEN];
char hst[MNAMELEN];
size_t len;
u_char nfh[NFSX_V3FHMAX];
@ -810,10 +810,6 @@ nfs_mount(mp, path, data, ndp, p)
error = copyin((caddr_t)args.fh, (caddr_t)nfh, args.fhsize);
if (error)
return (error);
error = copyinstr(path, pth, MNAMELEN-1, &len);
if (error)
return (error);
bzero(&pth[len], MNAMELEN - len);
error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
if (error)
return (error);
@ -823,7 +819,7 @@ nfs_mount(mp, path, data, ndp, p)
if (error)
return (error);
args.fh = nfh;
error = mountnfs(&args, mp, nam, pth, hst, &vp);
error = mountnfs(&args, mp, nam, path, hst, &vp);
return (error);
}

View File

@ -764,7 +764,7 @@ nfs_mount(mp, path, data, ndp, p)
struct nfs_args args;
struct sockaddr *nam;
struct vnode *vp;
char pth[MNAMELEN], hst[MNAMELEN];
char hst[MNAMELEN];
size_t len;
u_char nfh[NFSX_V3FHMAX];
@ -810,10 +810,6 @@ nfs_mount(mp, path, data, ndp, p)
error = copyin((caddr_t)args.fh, (caddr_t)nfh, args.fhsize);
if (error)
return (error);
error = copyinstr(path, pth, MNAMELEN-1, &len);
if (error)
return (error);
bzero(&pth[len], MNAMELEN - len);
error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
if (error)
return (error);
@ -823,7 +819,7 @@ nfs_mount(mp, path, data, ndp, p)
if (error)
return (error);
args.fh = nfh;
error = mountnfs(&args, mp, nam, pth, hst, &vp);
error = mountnfs(&args, mp, nam, path, hst, &vp);
return (error);
}

View File

@ -376,16 +376,12 @@ ntfs_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.
* error occurs, the mountpoint is discarded by the
* upper level code. Note that vfs_mount() handles
* copying the mountpoint f_mntonname for us, so we
* don't have to do it here unless we want to set it
* to something other than "path" for some rason.
*/
/* 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*/

View File

@ -146,7 +146,6 @@ static int nwfs_mount(struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct proc *p)
{
struct nwfs_args args; /* will hold data from mount request */
size_t size;
int error;
struct nwmount *nmp = NULL;
struct ncp_conn *conn = NULL;
@ -198,8 +197,6 @@ static int nwfs_mount(struct mount *mp, char *path, caddr_t data,
nmp->m.dir_mode = (nmp->m.dir_mode &
(S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
if ((error = nwfs_initnls(nmp)) != 0) goto bad;
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
pc = mp->mnt_stat.f_mntfromname;
pe = pc+sizeof(mp->mnt_stat.f_mntfromname);
bzero(pc, MNAMELEN);

View File

@ -404,7 +404,8 @@ extern char *mountrootfsname;
* exported vnode operations
*/
int dounmount __P((struct mount *, int, struct proc *));
int mount1 __P((struct proc *p, struct mount_args *uap, int segflag));
int vfs_mount __P((struct proc *p, char *type, char *path, int flags,
void *data));
int vfs_setpublicfs /* set publicly exported fs */
__P((struct mount *, struct netexport *, struct export_args *));
int vfs_lock __P((struct mount *)); /* lock a vfs */

View File

@ -323,9 +323,8 @@ ffs_mount(mp, path, data, ndp, p)
* We need the name for the mount point (also used for
* "last mounted on") copied in. If an error occurs,
* the mount point is discarded by the upper level code.
* Note that vfs_mount() populates f_mntonname for us.
*/
copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
if ((error = ffs_mountfs(devvp, mp, p, M_FFSNODE)) != 0) {
vrele(devvp);
return (error);