diff mbox series

[v2,042/108] linux-user: Split out fstatfs, fstatfs64, statfs, statfs64

Message ID 20180610030220.3777-43-richard.henderson@linaro.org
State New
Headers show
Series linux-user: Split do_syscall | expand

Commit Message

Richard Henderson June 10, 2018, 3:01 a.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 linux-user/syscall.c | 193 ++++++++++++++++++++++++++++---------------
 1 file changed, 125 insertions(+), 68 deletions(-)

-- 
2.17.1
diff mbox series

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index df8422cd3a..86583988c4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -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);