diff mbox

[v7,05/10] linux-user: Add support for ustat() syscall

Message ID 20160922165712.79809-6-aleksandar.markovic@rt-rk.com (mailing list archive)
State New, archived
Headers show

Commit Message

Aleksandar Markovic Sept. 22, 2016, 4:56 p.m. UTC
From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

This patch implements Qemu user mode ustat() syscall support.

Syscall ustat() returns information about a mounted filesystem.

Its declaration is:

int ustat(dev_t dev, struct ustat *ubuf);

Its Linux kernel implementation is at fs/compat.c, line 334.

The Qemu implementation proposed in this patch is similar to the
Qemu implementations of statfs(), fstatfs() and other related syscalls.
It is based on invocation of host's ustat(), and its key part is in the
correspondent case segment of the main switch statement of the function
do_syscall(), in file linux-user/syscalls.c. All necessary conversions
of data structures from target to host and from host to target are
covered. Support for target_ustat is included. Sufficient support for
"-strace" option for this syscall is already present, and this patch
does not change it.

This patch also fixes failures of LTP tests ustat01, and ustat02, if
executed on Qemu-emulated systems.

Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
 linux-user/syscall.c      | 23 +++++++++++++++++++++--
 linux-user/syscall_defs.h |  6 ++++++
 2 files changed, 27 insertions(+), 2 deletions(-)

Comments

Riku Voipio Oct. 21, 2016, 5:04 p.m. UTC | #1
On Thu, Sep 22, 2016 at 06:56:54PM +0200, Aleksandar Markovic wrote:
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> This patch implements Qemu user mode ustat() syscall support.
> 
> Syscall ustat() returns information about a mounted filesystem.
> 
> Its declaration is:
> 
> int ustat(dev_t dev, struct ustat *ubuf);
> 
> Its Linux kernel implementation is at fs/compat.c, line 334.
> 
> The Qemu implementation proposed in this patch is similar to the
> Qemu implementations of statfs(), fstatfs() and other related syscalls.
> It is based on invocation of host's ustat(), and its key part is in the
> correspondent case segment of the main switch statement of the function
> do_syscall(), in file linux-user/syscalls.c. All necessary conversions
> of data structures from target to host and from host to target are
> covered. Support for target_ustat is included. Sufficient support for
> "-strace" option for this syscall is already present, and this patch
> does not change it.
> 
> This patch also fixes failures of LTP tests ustat01, and ustat02, if
> executed on Qemu-emulated systems.

Had to drop this patch from my series. Not all platforms implement
ustat anymore. As Peter suggested, it is probably better implement ustat
with calling statvfs or statfs.
 
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
>  linux-user/syscall.c      | 23 +++++++++++++++++++++--
>  linux-user/syscall_defs.h |  6 ++++++
>  2 files changed, 27 insertions(+), 2 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 563796a..d28f3e6 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -48,6 +48,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
>  #include <sys/shm.h>
>  #include <sys/sem.h>
>  #include <sys/statfs.h>
> +#include <ustat.h>
>  #include <utime.h>
>  #include <sys/sysinfo.h>
>  #include <sys/signalfd.h>
> @@ -8226,9 +8227,27 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          ret = get_errno(chroot(p));
>          unlock_user(p, arg1, 0);
>          break;
> -#ifdef TARGET_NR_ustat
> +#if defined(TARGET_NR_ustat)
>      case TARGET_NR_ustat:
> -        goto unimplemented;
> +        {
> +            struct ustat ust;
> +
> +            ret = get_errno(ustat(arg1, &ust));
> +            if (!is_error(ret)) {
> +                struct target_ustat *target_ust;
> +
> +                if (!lock_user_struct(VERIFY_WRITE, target_ust, arg2, 0)) {
> +                    goto efault;
> +                }
> +                __put_user(ust.f_tfree, &target_ust->f_tfree);
> +                __put_user(ust.f_tinode, &target_ust->f_tinode);
> +                memcpy(target_ust->f_fname, ust.f_fname, 6);
> +                memcpy(target_ust->f_fpack, ust.f_fpack, 6);
> +                unlock_user_struct(target_ust, arg2, 1);
> +            }
> +        }
> +        break;
> +
>  #endif
>  #ifdef TARGET_NR_dup2
>      case TARGET_NR_dup2:
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index e47a61a..2c183d1 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -2164,6 +2164,12 @@ struct target_statfs64 {
>  };
>  #endif
>  
> +struct target_ustat {
> +        abi_ulong f_tfree;
> +        abi_int f_tinode;
> +        char f_fname[6];
> +        char f_fpack[6];
> +};
>  
>  #define TARGET_F_DUPFD         0       /* dup */
>  #define TARGET_F_GETFD         1       /* get close_on_exec */
> -- 
> 2.9.3
>
Aleksandar Markovic Oct. 21, 2016, 6:01 p.m. UTC | #2
Sure, thanks for all other efforts that you put regarding my patches.

I may post another version in some time. There is no rush wrt 2.8 as far as I am concerned.

-------- Original Message --------
Subject: Re: [PATCH v7 05/10] linux-user: Add support for ustat() syscall
Date: Friday, October 21, 2016 19:04 CEST
From: Riku Voipio <riku.voipio@iki.fi>
To: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
CC: qemu-devel@nongnu.org, laurent@vivier.eu, peter.maydell@linaro.org, petar.jovanovic@imgtec.com, miodrag.dinic@imgtec.com, aleksandar.rikalo@imgtec.com, aleksandar.markovic@imgtec.com
References: <20160922165712.79809-1-aleksandar.markovic@rt-rk.com> <20160922165712.79809-6-aleksandar.markovic@rt-rk.com>


 On Thu, Sep 22, 2016 at 06:56:54PM +0200, Aleksandar Markovic wrote:
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
>
> This patch implements Qemu user mode ustat() syscall support.
>
> Syscall ustat() returns information about a mounted filesystem.
>
> Its declaration is:
>
> int ustat(dev_t dev, struct ustat *ubuf);
>
> Its Linux kernel implementation is at fs/compat.c, line 334.
>
> The Qemu implementation proposed in this patch is similar to the
> Qemu implementations of statfs(), fstatfs() and other related syscalls.
> It is based on invocation of host's ustat(), and its key part is in the
> correspondent case segment of the main switch statement of the function
> do_syscall(), in file linux-user/syscalls.c. All necessary conversions
> of data structures from target to host and from host to target are
> covered. Support for target_ustat is included. Sufficient support for
> "-strace" option for this syscall is already present, and this patch
> does not change it.
>
> This patch also fixes failures of LTP tests ustat01, and ustat02, if
> executed on Qemu-emulated systems.

Had to drop this patch from my series. Not all platforms implement
ustat anymore. As Peter suggested, it is probably better implement ustat
with calling statvfs or statfs.

> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
> linux-user/syscall.c | 23 +++++++++++++++++++++--
> linux-user/syscall_defs.h | 6 ++++++
> 2 files changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 563796a..d28f3e6 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -48,6 +48,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
> #include <sys/shm.h>
> #include <sys/sem.h>
> #include <sys/statfs.h>
> +#include <ustat.h>
> #include <utime.h>
> #include <sys/sysinfo.h>
> #include <sys/signalfd.h>
> @@ -8226,9 +8227,27 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
> ret = get_errno(chroot(p));
> unlock_user(p, arg1, 0);
> break;
> -#ifdef TARGET_NR_ustat
> +#if defined(TARGET_NR_ustat)
> case TARGET_NR_ustat:
> - goto unimplemented;
> + {
> + struct ustat ust;
> +
> + ret = get_errno(ustat(arg1, &ust));
> + if (!is_error(ret)) {
> + struct target_ustat *target_ust;
> +
> + if (!lock_user_struct(VERIFY_WRITE, target_ust, arg2, 0)) {
> + goto efault;
> + }
> + __put_user(ust.f_tfree, &target_ust->f_tfree);
> + __put_user(ust.f_tinode, &target_ust->f_tinode);
> + memcpy(target_ust->f_fname, ust.f_fname, 6);
> + memcpy(target_ust->f_fpack, ust.f_fpack, 6);
> + unlock_user_struct(target_ust, arg2, 1);
> + }
> + }
> + break;
> +
> #endif
> #ifdef TARGET_NR_dup2
> case TARGET_NR_dup2:
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index e47a61a..2c183d1 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -2164,6 +2164,12 @@ struct target_statfs64 {
> };
> #endif
>
> +struct target_ustat {
> + abi_ulong f_tfree;
> + abi_int f_tinode;
> + char f_fname[6];
> + char f_fpack[6];
> +};
>
> #define TARGET_F_DUPFD 0 /* dup */
> #define TARGET_F_GETFD 1 /* get close_on_exec */
> --
> 2.9.3
>
diff mbox

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 563796a..d28f3e6 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -48,6 +48,7 @@  int __clone2(int (*fn)(void *), void *child_stack_base,
 #include <sys/shm.h>
 #include <sys/sem.h>
 #include <sys/statfs.h>
+#include <ustat.h>
 #include <utime.h>
 #include <sys/sysinfo.h>
 #include <sys/signalfd.h>
@@ -8226,9 +8227,27 @@  abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(chroot(p));
         unlock_user(p, arg1, 0);
         break;
-#ifdef TARGET_NR_ustat
+#if defined(TARGET_NR_ustat)
     case TARGET_NR_ustat:
-        goto unimplemented;
+        {
+            struct ustat ust;
+
+            ret = get_errno(ustat(arg1, &ust));
+            if (!is_error(ret)) {
+                struct target_ustat *target_ust;
+
+                if (!lock_user_struct(VERIFY_WRITE, target_ust, arg2, 0)) {
+                    goto efault;
+                }
+                __put_user(ust.f_tfree, &target_ust->f_tfree);
+                __put_user(ust.f_tinode, &target_ust->f_tinode);
+                memcpy(target_ust->f_fname, ust.f_fname, 6);
+                memcpy(target_ust->f_fpack, ust.f_fpack, 6);
+                unlock_user_struct(target_ust, arg2, 1);
+            }
+        }
+        break;
+
 #endif
 #ifdef TARGET_NR_dup2
     case TARGET_NR_dup2:
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index e47a61a..2c183d1 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2164,6 +2164,12 @@  struct target_statfs64 {
 };
 #endif
 
+struct target_ustat {
+        abi_ulong f_tfree;
+        abi_int f_tinode;
+        char f_fname[6];
+        char f_fpack[6];
+};
 
 #define TARGET_F_DUPFD         0       /* dup */
 #define TARGET_F_GETFD         1       /* get close_on_exec */