Subject: port-amd64/35956: linux32 statfs
To: None <port-amd64-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: None <ef@math.uni-bonn.de>
List: netbsd-bugs
Date: 03/09/2007 10:30:00
>Number: 35956
>Category: port-amd64
>Synopsis: COMPAT_LINUX32 lacks statfs(2)
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-amd64-maintainer
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Fri Mar 09 10:30:00 +0000 2007
>Originator: Edgar Fuß
>Release: NetBSD 4.0_BETA2
>Organization:
Mathematisches Institut der Universität Bonn, Computerabteilung
>Environment:
System: NetBSD jade.math.uni-bonn.de 4.0_BETA2 NetBSD 4.0_BETA2 (WAP05-Server) #2: Thu Mar 8 17:14:41 CET 2007 root@weser.math.uni-bonn.de:/var/tmp/obj-4.0
beta2/sys/arch/amd64/compile/wap05serv amd64
Architecture: x86_64
Machine: amd64
>Description:
32-Bit Linux emulation does not incorporate the statfs syscall.
The Tivoli client (dsmc) seems to need it (or statfs64)
I was asked on port-amd64 to send-pr this.
>How-To-Repeat:
sys 99
>Fix:
--- sys/compat/linux32/arch/amd64/syscalls.master.orig 2006-09-13 21:55:49.000000000 +0200
+++ sys/compat/linux32/arch/amd64/syscalls.master 2007-03-08 17:03:19.000000000 +0100
@@ -191,7 +191,8 @@
96 STD { int linux32_sys_getpriority(int which, int who); }
97 STD { int linux32_sys_setpriority(int which, int who, int prio); }
98 UNIMPL profil
-99 UNIMPL statfs
+99 STD { int linux32_sys_statfs(const netbsd32_charp path, \
+ linux32_statfsp sp); }
100 UNIMPL fstatfs
101 UNIMPL ioperm
102 STD { int linux32_sys_socketcall(int what, netbsd32_voidp args); }
--- sys/compat/linux32/files.linux32.orig 2006-09-13 21:55:49.000000000 +0200
+++ sys/compat/linux32/files.linux32 2007-03-08 14:57:12.000000000 +0100
@@ -11,6 +11,7 @@
file compat/linux32/common/linux32_exec_elf32.c compat_linux32 & exec_elf32
file compat/linux32/common/linux32_fcntl.c compat_linux32
file compat/linux32/common/linux32_ioctl.c compat_linux32
+file compat/linux32/common/linux32_misc.c compat_linux32
file compat/linux32/common/linux32_mman.c compat_linux32
file compat/linux32/common/linux32_resource.c compat_linux32
file compat/linux32/common/linux32_sched.c compat_linux32
--- sys/compat/linux/common/linux_misc.c.orig 2006-11-16 02:32:42.000000000 +0100
+++ sys/compat/linux/common/linux_misc.c 2007-03-08 15:42:01.000000000 +0100
@@ -177,11 +177,10 @@
#define DPRINTF(a)
# endif
-/* Local linux_misc.c functions: */
-# ifndef __amd64__
-static void bsd_to_linux_statfs __P((const struct statvfs *,
+/* needed by linux32_sys_statfs */
+void bsd_to_linux_statfs __P((const struct statvfs *,
struct linux_statfs *));
-# endif
+/* Local linux_misc.c functions: */
static void linux_to_bsd_mmap_args __P((struct sys_mmap_args *,
const struct linux_sys_mmap_args *));
static int linux_mmap __P((struct lwp *, struct linux_sys_mmap_args *,
@@ -313,13 +312,12 @@
return 0;
}
-# ifndef __amd64__
/*
* 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
+void
bsd_to_linux_statfs(bsp, lsp)
const struct statvfs *bsp;
struct linux_statfs *lsp;
@@ -365,6 +363,7 @@
(void)memset(lsp->l_fspare, 0, sizeof(lsp->l_fspare));
}
+# ifndef __amd64__
/*
* Implement the fs stat functions. Straightforward.
*/
--- sys/compat/linux32/common/linux32_types.h.orig 2006-11-16 02:32:44.000000000 +0100
+++ sys/compat/linux32/common/linux32_types.h 2007-03-08 16:59:51.000000000 +0100
@@ -1,4 +1,4 @@
-/* $NetBSD: linux32_types.h,v 1.3 2006/11/16 01:32:44 christos Exp $ */
+/* $NetBSD: linux32_types.h,v $ */
/*-
* Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
@@ -42,6 +42,8 @@
typedef netbsd32_pointer_t linux32_utsnamep;
typedef netbsd32_pointer_t linux32_stat64p;
typedef netbsd32_pointer_t linux32_statp;
+typedef netbsd32_pointer_t linux32_statfs64p;
+typedef netbsd32_pointer_t linux32_statfsp;
typedef netbsd32_pointer_t linux32_sigactionp_t;
typedef netbsd32_pointer_t linux32_sigsetp_t;
typedef netbsd32_pointer_t linux32___sysctlp_t;
--- /dev/null 2007-03-08 17:45:23.000000000 +0100
+++ sys/compat/linux32/common/linux32_misc.c 2007-03-08 17:47:22.000000000 +0100
@@ -0,0 +1,144 @@
+/* $NetBSD: linux32_misc.c,v $ */
+
+/*-
+ * Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Frank van der Linden and Eric Haszlakiewicz; by Jason R. Thorpe
+ * of the Numerical Aerospace Simulation Facility, NASA Ames Research Center;
+ * by Edgar Fu\ss, Mathematisches Institut der Uni Bonn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v $");
+
+#if defined(_KERNEL_OPT)
+#include "opt_ptrace.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/namei.h>
+#include <sys/proc.h>
+#include <sys/dirent.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/filedesc.h>
+#include <sys/ioctl.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <sys/utsname.h>
+#include <sys/unistd.h>
+
+#include <sys/sa.h>
+#include <sys/syscall.h>
+#include <sys/syscallargs.h>
+
+#include <compat/netbsd32/netbsd32.h>
+#include <compat/netbsd32/netbsd32_conv.h>
+#include <compat/netbsd32/netbsd32_syscallargs.h>
+
+#include <compat/linux32/common/linux32_machdep.h>
+#include <compat/linux32/common/linux32_types.h>
+#include <compat/linux32/common/linux32_signal.h>
+#include <compat/linux32/common/linux32_sysctl.h>
+#include <compat/linux32/linux32_syscallargs.h>
+
+#include <compat/linux/common/linux_machdep.h>
+#include <compat/linux/common/linux_types.h>
+#include <compat/linux/common/linux_util.h>
+#include <compat/linux/common/linux_misc.h>
+#include <compat/linux/common/linux_emuldata.h>
+#include <compat/linux/linux_syscallargs.h>
+
+
+extern const struct linux_mnttypes linux_fstypes[];
+extern const int linux_fstypes_cnt;
+
+# ifdef DEBUG_LINUX
+#define DPRINTF(a) uprintf a
+# else
+#define DPRINTF(a)
+# endif
+
+void bsd_to_linux_statfs __P((const struct statvfs *,
+ struct linux_statfs *));
+
+/*
+ * Implement the fs stat functions. Straightforward.
+ */
+int
+linux32_sys_statfs(l, v, retval)
+ struct lwp *l;
+ void *v;
+ register_t *retval;
+{
+ struct linux32_sys_statfs_args /* {
+ syscallarg(const netbsd32_charp char) path;
+ syscallarg(struct linux_statfs *) sp;
+ } */ *uap = v;
+ struct proc *p = l->l_proc;
+ struct statvfs *btmp, *bsp;
+ struct linux_statfs ltmp;
+ struct sys_statvfs1_args bsa;
+ caddr_t sg;
+ int error;
+
+ sg = stackgap_init(p, 0);
+ bsp = stackgap_alloc(p, &sg, sizeof (struct statvfs));
+
+ NETBSD32TOP(uap, &bsa, path, const char);
+ CHECK_ALT_EXIST(l, &sg, SCARG(&bsa, path));
+
+ SCARG(&bsa, buf) = bsp;
+ SCARG(&bsa, flags) = ST_WAIT;
+
+ if ((error = sys_statvfs1(l, &bsa, retval)))
+ return error;
+
+ btmp = STATVFSBUF_GET();
+ error = copyin(bsp, btmp, sizeof(*btmp));
+ if (error) {
+ goto out;
+ }
+ bsd_to_linux_statfs(btmp, <mp);
+ error = copyout(<mp, NETBSD32PTR64(SCARG(uap, sp)), sizeof ltmp);
+out:
+ STATVFSBUF_PUT(btmp);
+ return error;
+}