Module Name: src Committed By: chs Date: Tue Nov 2 18:14:06 UTC 2010
Modified Files: src/sys/compat/linux/common: linux_misc_notalpha.c linux_statfs.h src/sys/compat/linux32/arch/amd64: linux32_machdep.c syscalls.master src/sys/compat/linux32/common: linux32_misc.c linux32_types.h Log Message: implement the following syscalls for linux32: truncate64 ftruncate64 profil ioperm iopl setdomainname modify_ldt statfs64 fstatfs64 note that iopl(), ioperm() and modify_ldt() just call the respective 64-bit handlers, which don't do anything yet. To generate a diff of this commit: cvs rdiff -u -r1.107 -r1.108 \ src/sys/compat/linux/common/linux_misc_notalpha.c cvs rdiff -u -r1.4 -r1.5 src/sys/compat/linux/common/linux_statfs.h cvs rdiff -u -r1.26 -r1.27 \ src/sys/compat/linux32/arch/amd64/linux32_machdep.c cvs rdiff -u -r1.56 -r1.57 src/sys/compat/linux32/arch/amd64/syscalls.master cvs rdiff -u -r1.19 -r1.20 src/sys/compat/linux32/common/linux32_misc.c cvs rdiff -u -r1.13 -r1.14 src/sys/compat/linux32/common/linux32_types.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/compat/linux/common/linux_misc_notalpha.c diff -u src/sys/compat/linux/common/linux_misc_notalpha.c:1.107 src/sys/compat/linux/common/linux_misc_notalpha.c:1.108 --- src/sys/compat/linux/common/linux_misc_notalpha.c:1.107 Wed Jul 7 01:30:35 2010 +++ src/sys/compat/linux/common/linux_misc_notalpha.c Tue Nov 2 18:14:05 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_misc_notalpha.c,v 1.107 2010/07/07 01:30:35 chs Exp $ */ +/* $NetBSD: linux_misc_notalpha.c,v 1.108 2010/11/02 18:14:05 chs Exp $ */ /*- * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc. @@ -31,7 +31,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.107 2010/07/07 01:30:35 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.108 2010/11/02 18:14:05 chs Exp $"); + +/* + * Note that we must NOT include "opt_compat_linux32.h" here, + * the maze of ifdefs below relies on COMPAT_LINUX32 only being + * defined when this file is built for linux32. + */ #include <sys/param.h> #include <sys/systm.h> @@ -61,6 +67,7 @@ #include <compat/linux/common/linux_util.h> #include <compat/linux/common/linux_ipc.h> #include <compat/linux/common/linux_sem.h> +#include <compat/linux/common/linux_statfs.h> #include <compat/linux/linux_syscallargs.h> @@ -79,10 +86,6 @@ #endif #ifndef COMPAT_LINUX32 -#if !defined(__amd64__) -static void bsd_to_linux_statfs64(const struct statvfs *, - struct linux_statfs64 *); -#endif /* * Alarm. This is a libc call which uses setitimer(2) in NetBSD. @@ -401,49 +404,6 @@ return 0; } -#endif /* !amd64 */ - -#if !defined(__amd64__) -/* - * Convert NetBSD statvfs structure to Linux statfs64 structure. - * See comments in bsd_to_linux_statfs() for further background. - * We can safely pass correct bsize and frsize here, since Linux glibc - * statvfs() doesn't use statfs64(). - */ -static void -bsd_to_linux_statfs64(const struct statvfs *bsp, struct linux_statfs64 *lsp) -{ - int i, div; - - for (i = 0; i < linux_fstypes_cnt; i++) { - if (strcmp(bsp->f_fstypename, linux_fstypes[i].bsd) == 0) { - lsp->l_ftype = linux_fstypes[i].linux; - break; - } - } - - if (i == linux_fstypes_cnt) { - DPRINTF(("unhandled fstype in linux emulation: %s\n", - bsp->f_fstypename)); - lsp->l_ftype = LINUX_DEFAULT_SUPER_MAGIC; - } - - div = bsp->f_frsize ? (bsp->f_bsize / bsp->f_frsize) : 1; - if (div == 0) - div = 1; - lsp->l_fbsize = bsp->f_bsize; - lsp->l_ffrsize = bsp->f_frsize; - lsp->l_fblocks = bsp->f_blocks / div; - lsp->l_fbfree = bsp->f_bfree / div; - lsp->l_fbavail = bsp->f_bavail / div; - lsp->l_ffiles = bsp->f_files; - lsp->l_fffree = bsp->f_ffree / div; - /* Linux sets the fsid to 0..., we don't */ - lsp->l_ffsid.val[0] = bsp->f_fsidx.__fsid_val[0]; - lsp->l_ffsid.val[1] = bsp->f_fsidx.__fsid_val[1]; - lsp->l_fnamelen = bsp->f_namemax; - (void)memset(lsp->l_fspare, 0, sizeof(lsp->l_fspare)); -} /* * Implement the fs stat functions. Straightforward. @@ -497,5 +457,5 @@ STATVFSBUF_PUT(sb); return error; } -#endif /* !__m68k__ && !__amd64__ */ +#endif /* !__amd64__ */ #endif /* !COMPAT_LINUX32 */ Index: src/sys/compat/linux/common/linux_statfs.h diff -u src/sys/compat/linux/common/linux_statfs.h:1.4 src/sys/compat/linux/common/linux_statfs.h:1.5 --- src/sys/compat/linux/common/linux_statfs.h:1.4 Sun Mar 15 15:55:51 2009 +++ src/sys/compat/linux/common/linux_statfs.h Tue Nov 2 18:14:05 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_statfs.h,v 1.4 2009/03/15 15:55:51 cegger Exp $ */ +/* $NetBSD: linux_statfs.h,v 1.5 2010/11/02 18:14:05 chs Exp $ */ /*- * Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc. @@ -33,15 +33,17 @@ #ifndef _LINUX_STATFS_H #define _LINUX_STATFS_H -static void bsd_to_linux_statfs(const struct statvfs *, +static void __unused bsd_to_linux_statfs(const struct statvfs *, struct linux_statfs *); +static void __unused bsd_to_linux_statfs64(const struct statvfs *, + struct linux_statfs64 *); /* * Convert NetBSD statvfs structure to Linux statfs structure. * Linux doesn't have f_flag, and we can't set f_frsize due * to glibc statvfs() bug (see below). */ -static void +static void __unused bsd_to_linux_statfs(const struct statvfs *bsp, struct linux_statfs *lsp) { int i; @@ -83,4 +85,43 @@ (void)memset(lsp->l_fspare, 0, sizeof(lsp->l_fspare)); } +/* + * Convert NetBSD statvfs structure to Linux statfs64 structure. + * See comments in bsd_to_linux_statfs() for further background. + * We can safely pass correct bsize and frsize here, since Linux glibc + * statvfs() doesn't use statfs64(). + */ +static void __unused +bsd_to_linux_statfs64(const struct statvfs *bsp, struct linux_statfs64 *lsp) +{ + int i, div; + + for (i = 0; i < linux_fstypes_cnt; i++) { + if (strcmp(bsp->f_fstypename, linux_fstypes[i].bsd) == 0) { + lsp->l_ftype = linux_fstypes[i].linux; + break; + } + } + + if (i == linux_fstypes_cnt) { + lsp->l_ftype = LINUX_DEFAULT_SUPER_MAGIC; + } + + div = bsp->f_frsize ? (bsp->f_bsize / bsp->f_frsize) : 1; + if (div == 0) + div = 1; + lsp->l_fbsize = bsp->f_bsize; + lsp->l_ffrsize = bsp->f_frsize; + lsp->l_fblocks = bsp->f_blocks / div; + lsp->l_fbfree = bsp->f_bfree / div; + lsp->l_fbavail = bsp->f_bavail / div; + lsp->l_ffiles = bsp->f_files; + lsp->l_fffree = bsp->f_ffree / div; + /* Linux sets the fsid to 0..., we don't */ + lsp->l_ffsid.val[0] = bsp->f_fsidx.__fsid_val[0]; + lsp->l_ffsid.val[1] = bsp->f_fsidx.__fsid_val[1]; + lsp->l_fnamelen = bsp->f_namemax; + (void)memset(lsp->l_fspare, 0, sizeof(lsp->l_fspare)); +} + #endif /* !_LINUX_STATFS_H */ Index: src/sys/compat/linux32/arch/amd64/linux32_machdep.c diff -u src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.26 src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.27 --- src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.26 Mon Jul 12 02:55:17 2010 +++ src/sys/compat/linux32/arch/amd64/linux32_machdep.c Tue Nov 2 18:14:06 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: linux32_machdep.c,v 1.26 2010/07/12 02:55:17 christos Exp $ */ +/* $NetBSD: linux32_machdep.c,v 1.27 2010/11/02 18:14:06 chs Exp $ */ /*- * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. @@ -31,7 +31,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.26 2010/07/12 02:55:17 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.27 2010/11/02 18:14:06 chs Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -513,3 +513,19 @@ /* glibc doesn't actually call this. */ return ENOSYS; } + +int +linux32_sys_modify_ldt(struct lwp *l, const struct linux32_sys_modify_ldt_args *uap, register_t *retval) +{ + /* { + syscallarg(int) func; + syscallarg(netbsd32_charp) ptr; + syscallarg(netbsd32_size_t) bytecount; + } */ + struct linux_sys_modify_ldt_args ua; + + NETBSD32TO64_UAP(func); + NETBSD32TOP_UAP(ptr, void *); + NETBSD32TOX_UAP(bytecount, size_t); + return linux_sys_modify_ldt(l, &ua, retval); +} Index: src/sys/compat/linux32/arch/amd64/syscalls.master diff -u src/sys/compat/linux32/arch/amd64/syscalls.master:1.56 src/sys/compat/linux32/arch/amd64/syscalls.master:1.57 --- src/sys/compat/linux32/arch/amd64/syscalls.master:1.56 Wed Jul 7 01:30:35 2010 +++ src/sys/compat/linux32/arch/amd64/syscalls.master Tue Nov 2 18:14:06 2010 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.56 2010/07/07 01:30:35 chs Exp $ + $NetBSD: syscalls.master,v 1.57 2010/11/02 18:14:06 chs Exp $ ; NetBSD i386 COMPAT_LINUX32 system call name/number "master" file. ; (See syscalls.conf to see what it is processed into.) @@ -193,11 +193,14 @@ linux32_gid16_t gid); } 96 STD { int|linux32_sys||getpriority(int which, int who); } 97 NOARGS { int|netbsd32||setpriority(int which, int who, int prio); } -98 UNIMPL profil +98 NOARGS { int|netbsd32||profil(netbsd32_voidp samples, \ + netbsd32_size_t size, netbsd32_u_long offset, \ + u_int scale); } 99 STD { int|linux32_sys||statfs(netbsd32_charp path, \ linux32_statfsp sp); } 100 STD { int|linux32_sys||fstatfs(int fd, linux32_statfsp sp); } -101 UNIMPL ioperm +101 NOARGS { int|linux_sys||ioperm(unsigned int lo, \ + unsigned int hi, int val); } 102 STD { int|linux32_sys||socketcall(int what, netbsd32_voidp args); } 103 UNIMPL syslog 104 NOARGS { int|compat_50_netbsd32||setitimer(int which, \ @@ -211,7 +214,7 @@ 108 STD { int|linux32_sys||fstat(int fd, \ linux32_statp sp); } 109 STD { int|linux32_sys||olduname(linux32_oldutsnamep_t up); } -110 UNIMPL iopl +110 NOARGS { int|linux_sys||iopl(int level); } 111 UNIMPL vhangup 112 UNIMPL idle 113 UNIMPL vm86old @@ -226,9 +229,11 @@ 120 STD { int|linux32_sys||clone(int flags, netbsd32_voidp stack, \ netbsd32_voidp parent_tidptr, netbsd32_voidp tls, \ netbsd32_voidp child_tidptr); } -121 UNIMPL setdomainname +121 STD { int|linux32_sys||setdomainname(netbsd32_charp domainname, \ + int len); } 122 STD { int|linux32_sys||uname(linux32_utsnamep up); } -123 UNIMPL modify_ldt +123 STD { int|linux32_sys||modify_ldt(int func, netbsd32_charp ptr, \ + netbsd32_size_t bytecount); } 124 UNIMPL adjtimex 125 STD { int|linux32_sys||mprotect(netbsd32_voidp start, \ netbsd32_size_t len, int prot); } @@ -339,8 +344,10 @@ 192 STD { linux32_off_t|linux32_sys||mmap2(netbsd32_u_long addr, \ netbsd32_size_t len, int prot, int flags, int fd, \ linux32_off_t offset); } -193 UNIMPL truncate64 -194 UNIMPL ftruncate64 +193 STD { int|linux32_sys||truncate64(netbsd32_charp path, \ + uint32_t lenlo, uint32_t lenhi); } +194 STD { int|linux32_sys||ftruncate64(unsigned int fd, \ + uint32_t lenlo, uint32_t lenhi); } 195 STD { int|linux32_sys||stat64(netbsd32_charp path, \ linux32_stat64p sp); } 196 STD { int|linux32_sys||lstat64(netbsd32_charp path, \ @@ -440,8 +447,10 @@ linux32_timespecp_t tp); } 267 STD { int|linux32_sys||clock_nanosleep(clockid_t which, int flags, \ linux32_timespecp_t rqtp, linux32_timespecp_t rmtp); } -268 UNIMPL statfs64 -269 UNIMPL fstatfs64 +268 STD { int|linux32_sys||statfs64(netbsd32_charp path, \ + netbsd32_size_t sz, linux32_statfs64p sp); } +269 STD { int|linux32_sys||fstatfs64(int fd, \ + netbsd32_size_t sz, linux32_statfs64p sp); } 270 STD { int|linux32_sys||tgkill(int tgid, int tid, int sig); } 271 UNIMPL utimes 272 UNIMPL fadvise64_64 Index: src/sys/compat/linux32/common/linux32_misc.c diff -u src/sys/compat/linux32/common/linux32_misc.c:1.19 src/sys/compat/linux32/common/linux32_misc.c:1.20 --- src/sys/compat/linux32/common/linux32_misc.c:1.19 Wed Jul 7 01:30:35 2010 +++ src/sys/compat/linux32/common/linux32_misc.c Tue Nov 2 18:14:06 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: linux32_misc.c,v 1.19 2010/07/07 01:30:35 chs Exp $ */ +/* $NetBSD: linux32_misc.c,v 1.20 2010/11/02 18:14:06 chs Exp $ */ /*- * Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v 1.19 2010/07/07 01:30:35 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v 1.20 2010/11/02 18:14:06 chs Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -114,6 +114,50 @@ return error; } +int +linux32_sys_statfs64(struct lwp *l, const struct linux32_sys_statfs64_args *uap, register_t *retval) +{ + /* { + syscallarg(const netbsd32_charp char) path; + syscallarg(linux32_statfs64p) sp; + } */ + struct statvfs *sb; + struct linux_statfs64 ltmp; + int error; + + sb = STATVFSBUF_GET(); + error = do_sys_pstatvfs(l, SCARG_P32(uap, path), ST_WAIT, sb); + if (error == 0) { + bsd_to_linux_statfs64(sb, <mp); + error = copyout(<mp, SCARG_P32(uap, sp), sizeof ltmp); + } + + STATVFSBUF_PUT(sb); + return error; +} + +int +linux32_sys_fstatfs64(struct lwp *l, const struct linux32_sys_fstatfs64_args *uap, register_t *retval) +{ + /* { + syscallarg(int) fd; + syscallarg(linux32_statfs64p) sp; + } */ + struct statvfs *sb; + struct linux_statfs64 ltmp; + int error; + + sb = STATVFSBUF_GET(); + error = do_sys_fstatvfs(l, SCARG(uap, fd), ST_WAIT, sb); + if (error == 0) { + bsd_to_linux_statfs64(sb, <mp); + error = copyout(<mp, SCARG_P32(uap, sp), sizeof ltmp); + } + STATVFSBUF_PUT(sb); + + return error; +} + extern const int linux_ptrace_request_map[]; int @@ -261,6 +305,52 @@ struct linux_sys_get_robust_list_args ua; NETBSD32TOP_UAP(head, struct robust_list_head *); - NETBSD32TOP_UAP(head, size_t *); + NETBSD32TOP_UAP(len, size_t *); return linux_sys_get_robust_list(l, &ua, retval); } + +int +linux32_sys_truncate64(struct lwp *l, const struct linux32_sys_truncate64_args *uap, register_t *retval) +{ + /* { + syscallarg(netbsd32_charp) path; + syscallarg(off_t) length; + } */ + struct sys_truncate_args ua; + + /* Linux doesn't have the 'pad' pseudo-parameter */ + NETBSD32TOP_UAP(path, const char *); + SCARG(&ua, PAD) = 0; + SCARG(&ua, length) = ((off_t)SCARG(uap, lenhi) << 32) + SCARG(uap, lenlo); + return sys_truncate(l, &ua, retval); +} + +int +linux32_sys_ftruncate64(struct lwp *l, const struct linux32_sys_ftruncate64_args *uap, register_t *retval) +{ + /* { + syscallarg(unsigned int) fd; + syscallarg(off_t) length; + } */ + struct sys_ftruncate_args ua; + + /* Linux doesn't have the 'pad' pseudo-parameter */ + NETBSD32TO64_UAP(fd); + SCARG(&ua, PAD) = 0; + SCARG(&ua, length) = ((off_t)SCARG(uap, lenhi) << 32) + SCARG(uap, lenlo); + return sys_ftruncate(l, &ua, retval); +} + +int +linux32_sys_setdomainname(struct lwp *l, const struct linux32_sys_setdomainname_args *uap, register_t *retval) +{ + /* { + syscallarg(netbsd32_charp) domainname; + syscallarg(int) len; + } */ + struct linux_sys_setdomainname_args ua; + + NETBSD32TOP_UAP(domainname, char); + NETBSD32TO64_UAP(len); + return linux_sys_setdomainname(l, &ua, retval); +} Index: src/sys/compat/linux32/common/linux32_types.h diff -u src/sys/compat/linux32/common/linux32_types.h:1.13 src/sys/compat/linux32/common/linux32_types.h:1.14 --- src/sys/compat/linux32/common/linux32_types.h:1.13 Sat Sep 11 20:53:04 2010 +++ src/sys/compat/linux32/common/linux32_types.h Tue Nov 2 18:14:06 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: linux32_types.h,v 1.13 2010/09/11 20:53:04 chs Exp $ */ +/* $NetBSD: linux32_types.h,v 1.14 2010/11/02 18:14:06 chs Exp $ */ /*- * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. @@ -46,6 +46,7 @@ typedef netbsd32_pointer_t linux32_stat64p; typedef netbsd32_pointer_t linux32_statp; typedef netbsd32_pointer_t linux32_statfsp; +typedef netbsd32_pointer_t linux32_statfs64p; typedef netbsd32_pointer_t linux32_sigactionp_t; typedef netbsd32_pointer_t linux32_sigsetp_t; typedef netbsd32_pointer_t linux32___sysctlp_t;