summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2001-02-16 14:31:49 +0000
committerjlemon <jlemon@FreeBSD.org>2001-02-16 14:31:49 +0000
commitc7ba1f9694fa8b0335305d6b36f179a03a55fee9 (patch)
tree62247d63383508e8961a98d00ff66b72291651a0 /sys
parent65a56b38f14e356f543283221b0cc6ff39d53725 (diff)
downloadFreeBSD-src-c7ba1f9694fa8b0335305d6b36f179a03a55fee9.zip
FreeBSD-src-c7ba1f9694fa8b0335305d6b36f179a03a55fee9.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_subr.c36
-rw-r--r--sys/kern/vfs_extattr.c17
-rw-r--r--sys/kern/vfs_syscalls.c17
-rw-r--r--sys/sys/mount.h2
-rw-r--r--sys/sys/uio.h3
5 files changed, 67 insertions, 8 deletions
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c
index 6b51c5c..ac4bad6 100644
--- a/sys/kern/kern_subr.c
+++ b/sys/kern/kern_subr.c
@@ -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);
+}
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 178d2a2..709736c 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -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);
}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 178d2a2..709736c 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -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);
}
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 77ee4e5..ea5a71a 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -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 */
diff --git a/sys/sys/uio.h b/sys/sys/uio.h
index a2de90a..547dbad 100644
--- a/sys/sys/uio.h
+++ b/sys/sys/uio.h
@@ -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 */
OpenPOWER on IntegriCloud