@@ -7207,6 +7207,61 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
return 0;
}
+static abi_long host_to_target_statfs(abi_ulong target_addr,
+ struct statfs *stfs)
+{
+ struct target_statfs *target_stfs;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_stfs, target_addr, 0)) {
+ return -TARGET_EFAULT;
+ }
+ __put_user(stfs->f_type, &target_stfs->f_type);
+ __put_user(stfs->f_bsize, &target_stfs->f_bsize);
+ __put_user(stfs->f_blocks, &target_stfs->f_blocks);
+ __put_user(stfs->f_bfree, &target_stfs->f_bfree);
+ __put_user(stfs->f_bavail, &target_stfs->f_bavail);
+ __put_user(stfs->f_files, &target_stfs->f_files);
+ __put_user(stfs->f_ffree, &target_stfs->f_ffree);
+ __put_user(stfs->f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
+ __put_user(stfs->f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
+ __put_user(stfs->f_namelen, &target_stfs->f_namelen);
+ __put_user(stfs->f_frsize, &target_stfs->f_frsize);
+#ifdef _STATFS_F_FLAGS
+ __put_user(stfs->f_flags, &target_stfs->f_flags);
+#else
+ __put_user(0, &target_stfs->f_flags);
+#endif
+ memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
+ unlock_user_struct(target_stfs, target_addr, 1);
+ return 0;
+}
+
+#ifdef TARGET_NR_statfs64
+static abi_long host_to_target_statfs64(abi_ulong target_addr,
+ struct statfs *stfs)
+{
+ struct target_statfs64 *target_stfs;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_stfs, target_addr, 0)) {
+ return -TARGET_EFAULT;
+ }
+ __put_user(stfs->f_type, &target_stfs->f_type);
+ __put_user(stfs->f_bsize, &target_stfs->f_bsize);
+ __put_user(stfs->f_blocks, &target_stfs->f_blocks);
+ __put_user(stfs->f_bfree, &target_stfs->f_bfree);
+ __put_user(stfs->f_bavail, &target_stfs->f_bavail);
+ __put_user(stfs->f_files, &target_stfs->f_files);
+ __put_user(stfs->f_ffree, &target_stfs->f_ffree);
+ __put_user(stfs->f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
+ __put_user(stfs->f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
+ __put_user(stfs->f_namelen, &target_stfs->f_namelen);
+ __put_user(stfs->f_frsize, &target_stfs->f_frsize);
+ memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
+ unlock_user_struct(target_stfs, target_addr, 1);
+ return 0;
+}
+#endif
+
/* ??? Using host futex calls even when target atomic operations
are not really atomic probably breaks things. However implementing
futexes locally would make futexes shared between multiple processes
@@ -8111,6 +8166,32 @@ IMPL(fork)
}
#endif
+IMPL(fstatfs)
+{
+ struct statfs stfs;
+ abi_long ret;
+
+ ret = get_errno(fstatfs(arg1, &stfs));
+ if (!is_error(ret) && host_to_target_statfs(arg2, &stfs)) {
+ return -TARGET_EFAULT;
+ }
+ return ret;
+}
+
+#ifdef TARGET_NR_fstatfs64
+IMPL(fstatfs64)
+{
+ struct statfs stfs;
+ abi_long ret;
+
+ ret = get_errno(fstatfs(arg1, &stfs));
+ if (!is_error(ret) && host_to_target_statfs64(arg3, &stfs)) {
+ return -TARGET_EFAULT;
+ }
+ return ret;
+}
+#endif
+
IMPL(ftruncate)
{
return get_errno(ftruncate(arg1, arg2));
@@ -9485,6 +9566,42 @@ IMPL(ssetmask)
}
#endif
+IMPL(statfs)
+{
+ char *p = lock_user_string(arg1);
+ struct statfs stfs;
+ abi_long ret;
+
+ if (!p) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(statfs(path(p), &stfs));
+ unlock_user(p, arg1, 0);
+ if (!is_error(ret) && host_to_target_statfs(arg2, &stfs)) {
+ return -TARGET_EFAULT;
+ }
+ return ret;
+}
+
+#ifdef TARGET_NR_statfs64
+IMPL(statfs64)
+{
+ char *p = lock_user_string(arg1);
+ struct statfs stfs;
+ abi_long ret;
+
+ if (!p) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(statfs(path(p), &stfs));
+ unlock_user(p, arg1, 0);
+ if (!is_error(ret) && host_to_target_statfs64(arg3, &stfs)) {
+ return -TARGET_EFAULT;
+ }
+ return ret;
+}
+#endif
+
#ifdef TARGET_NR_stime
IMPL(stime)
{
@@ -9778,7 +9895,6 @@ static abi_long do_syscall1(void *cpu_env, unsigned num, abi_long arg1,
CPUState *cpu __attribute__((unused)) = ENV_GET_CPU(cpu_env);
abi_long ret;
struct stat st;
- struct statfs stfs;
void *p;
switch(num) {
@@ -9800,73 +9916,6 @@ static abi_long do_syscall1(void *cpu_env, unsigned num, abi_long arg1,
return ret;
case TARGET_NR_setpriority:
return get_errno(setpriority(arg1, arg2, arg3));
- case TARGET_NR_statfs:
- if (!(p = lock_user_string(arg1))) {
- return -TARGET_EFAULT;
- }
- ret = get_errno(statfs(path(p), &stfs));
- unlock_user(p, arg1, 0);
- convert_statfs:
- if (!is_error(ret)) {
- struct target_statfs *target_stfs;
-
- if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
- return -TARGET_EFAULT;
- __put_user(stfs.f_type, &target_stfs->f_type);
- __put_user(stfs.f_bsize, &target_stfs->f_bsize);
- __put_user(stfs.f_blocks, &target_stfs->f_blocks);
- __put_user(stfs.f_bfree, &target_stfs->f_bfree);
- __put_user(stfs.f_bavail, &target_stfs->f_bavail);
- __put_user(stfs.f_files, &target_stfs->f_files);
- __put_user(stfs.f_ffree, &target_stfs->f_ffree);
- __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
- __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
- __put_user(stfs.f_namelen, &target_stfs->f_namelen);
- __put_user(stfs.f_frsize, &target_stfs->f_frsize);
-#ifdef _STATFS_F_FLAGS
- __put_user(stfs.f_flags, &target_stfs->f_flags);
-#else
- __put_user(0, &target_stfs->f_flags);
-#endif
- memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
- unlock_user_struct(target_stfs, arg2, 1);
- }
- return ret;
- case TARGET_NR_fstatfs:
- ret = get_errno(fstatfs(arg1, &stfs));
- goto convert_statfs;
-#ifdef TARGET_NR_statfs64
- case TARGET_NR_statfs64:
- if (!(p = lock_user_string(arg1))) {
- return -TARGET_EFAULT;
- }
- ret = get_errno(statfs(path(p), &stfs));
- unlock_user(p, arg1, 0);
- convert_statfs64:
- if (!is_error(ret)) {
- struct target_statfs64 *target_stfs;
-
- if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
- return -TARGET_EFAULT;
- __put_user(stfs.f_type, &target_stfs->f_type);
- __put_user(stfs.f_bsize, &target_stfs->f_bsize);
- __put_user(stfs.f_blocks, &target_stfs->f_blocks);
- __put_user(stfs.f_bfree, &target_stfs->f_bfree);
- __put_user(stfs.f_bavail, &target_stfs->f_bavail);
- __put_user(stfs.f_files, &target_stfs->f_files);
- __put_user(stfs.f_ffree, &target_stfs->f_ffree);
- __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
- __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
- __put_user(stfs.f_namelen, &target_stfs->f_namelen);
- __put_user(stfs.f_frsize, &target_stfs->f_frsize);
- memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
- unlock_user_struct(target_stfs, arg3, 1);
- }
- return ret;
- case TARGET_NR_fstatfs64:
- ret = get_errno(fstatfs(arg1, &stfs));
- goto convert_statfs64;
-#endif
#ifdef TARGET_NR_socketcall
case TARGET_NR_socketcall:
return do_socketcall(arg1, arg2);
@@ -12744,6 +12793,10 @@ static impl_fn *syscall_table(unsigned num)
#endif
#ifdef TARGET_NR_fork
SYSCALL(fork);
+#endif
+ SYSCALL(fstatfs);
+#ifdef TARGET_NR_fstatfs64
+ SYSCALL(fstatfs64);
#endif
SYSCALL(ftruncate);
#ifdef TARGET_NR_futimesat
@@ -12874,6 +12927,10 @@ static impl_fn *syscall_table(unsigned num)
#endif
#ifdef TARGET_NR_ssetmask
SYSCALL(ssetmask);
+#endif
+ SYSCALL(statfs);
+#ifdef TARGET_NR_statfs64
+ SYSCALL(statfs64);
#endif
#ifdef TARGET_NR_stime
SYSCALL(stime);
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/syscall.c | 193 ++++++++++++++++++++++++++++--------------- 1 file changed, 125 insertions(+), 68 deletions(-) -- 2.17.1