Introduce copyinfrom and copyinstrfrom, which can copy data from either

user or kernel space.  This will allow layering of os-compat (e.g.: linux)
system calls.  Apply the changes to mount.
This commit is contained in:
jlemon 2001-02-16 14:31:49 +00:00
parent 65a56b38f1
commit c7ba1f9694
5 changed files with 67 additions and 8 deletions

View File

@ -387,3 +387,39 @@ uio_yield()
PICKUP_GIANT();
splx(s);
}
int
copyinfrom(const void *src, void *dst, size_t len, int seg)
{
int error = 0;
switch (seg) {
case UIO_USERSPACE:
error = copyin(src, dst, len);
break;
case UIO_SYSSPACE:
bcopy(src, dst, len);
break;
default:
panic("copyinfrom: bad seg %d\n", seg);
}
return (error);
}
int
copyinstrfrom(const void *src, void *dst, size_t len, size_t *copied, int seg)
{
int error = 0;
switch (seg) {
case UIO_USERSPACE:
error = copyinstr(src, dst, len, copied);
break;
case UIO_SYSSPACE:
error = copystr(src, dst, len, copied);
break;
default:
panic("copyinstrfrom: bad seg %d\n", seg);
}
return (error);
}

View File

@ -107,12 +107,21 @@ struct mount_args {
int
mount(p, uap)
struct proc *p;
register struct mount_args /* {
struct mount_args *uap;
{
return (mount1(p, uap, UIO_USERSPACE));
}
int
mount1(p, uap, segflag)
struct proc *p;
struct mount_args /* {
syscallarg(char *) type;
syscallarg(char *) path;
syscallarg(int) flags;
syscallarg(caddr_t) data;
} */ *uap;
int segflag;
{
struct vnode *vp;
struct mount *mp;
@ -140,8 +149,7 @@ mount(p, uap)
/*
* Get vnode to be covered
*/
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
SCARG(uap, path), p);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, segflag, SCARG(uap, path), p);
if ((error = namei(&nd)) != 0)
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
@ -209,7 +217,8 @@ mount(p, uap)
vput(vp);
return (ENOTDIR);
}
if ((error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) != 0) {
if ((error = copyinstrfrom(SCARG(uap, type),
fstypename, MFSNAMELEN, NULL, segflag)) != 0) {
vput(vp);
return (error);
}

View File

@ -107,12 +107,21 @@ struct mount_args {
int
mount(p, uap)
struct proc *p;
register struct mount_args /* {
struct mount_args *uap;
{
return (mount1(p, uap, UIO_USERSPACE));
}
int
mount1(p, uap, segflag)
struct proc *p;
struct mount_args /* {
syscallarg(char *) type;
syscallarg(char *) path;
syscallarg(int) flags;
syscallarg(caddr_t) data;
} */ *uap;
int segflag;
{
struct vnode *vp;
struct mount *mp;
@ -140,8 +149,7 @@ mount(p, uap)
/*
* Get vnode to be covered
*/
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
SCARG(uap, path), p);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, segflag, SCARG(uap, path), p);
if ((error = namei(&nd)) != 0)
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
@ -209,7 +217,8 @@ mount(p, uap)
vput(vp);
return (ENOTDIR);
}
if ((error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) != 0) {
if ((error = copyinstrfrom(SCARG(uap, type),
fstypename, MFSNAMELEN, NULL, segflag)) != 0) {
vput(vp);
return (error);
}

View File

@ -312,6 +312,7 @@ extern struct vfsconf *vfsconf; /* head of list of filesystem types */
#ifdef __STDC__
struct nameidata;
struct mbuf;
struct mount_args;
#endif
struct vfsops {
@ -403,6 +404,7 @@ 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_setpublicfs /* set publicly exported fs */
__P((struct mount *, struct netexport *, struct export_args *));
int vfs_lock __P((struct mount *)); /* lock a vfs */

View File

@ -79,6 +79,9 @@ struct vm_object;
int uiomove __P((caddr_t, int, struct uio *));
int uiomoveco __P((caddr_t, int, struct uio *, struct vm_object *));
int uioread __P((int, struct uio *, struct vm_object *, int *));
int copyinfrom __P((const void *src, void *dst, size_t len, int seg));
int copyinstrfrom __P((const void *src, void *dst, size_t len,
size_t *copied, int seg));
#else /* !_KERNEL */