diff options
author | jlemon <jlemon@FreeBSD.org> | 2001-02-16 14:31:49 +0000 |
---|---|---|
committer | jlemon <jlemon@FreeBSD.org> | 2001-02-16 14:31:49 +0000 |
commit | c7ba1f9694fa8b0335305d6b36f179a03a55fee9 (patch) | |
tree | 62247d63383508e8961a98d00ff66b72291651a0 /sys | |
parent | 65a56b38f14e356f543283221b0cc6ff39d53725 (diff) | |
download | FreeBSD-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.c | 36 | ||||
-rw-r--r-- | sys/kern/vfs_extattr.c | 17 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 17 | ||||
-rw-r--r-- | sys/sys/mount.h | 2 | ||||
-rw-r--r-- | sys/sys/uio.h | 3 |
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 */ |