* [Qemu-devel] [PATCH v2] linux-user: Allow getdents to be provided by getdents64
@ 2013-06-04 11:12 Peter Maydell
2013-06-04 13:07 ` Richard Henderson
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Peter Maydell @ 2013-06-04 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Riku Voipio, Claudio Fontana, Laurent Vivier,
patches
Newer architectures may only implement the getdents64 syscall, not
getdents. Provide an implementation of getdents in terms of getdents64
so that we can run getdents-using targets on a getdents64-only host.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1370193044-24535-1-git-send-email-peter.maydell@linaro.org
---
Changes v1->v2:
* memmove() call moved to before we write inode/offset/reclen
* wrapped a stray long line that snuck in somehow
linux-user/syscall.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 60 insertions(+), 1 deletion(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0099d64..4151c78 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -223,8 +223,11 @@ static int gettid(void) {
return -ENOSYS;
}
#endif
+#ifdef __NR_getdents
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
-#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
+#endif
+#if !defined(__NR_getdents) || \
+ (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
#endif
#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
@@ -7123,6 +7126,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
#endif
case TARGET_NR_getdents:
+#ifdef __NR_getdents
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
{
struct target_dirent *target_dirp;
@@ -7195,6 +7199,61 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
unlock_user(dirp, arg2, ret);
}
#endif
+#else
+ /* Implement getdents in terms of getdents64 */
+ {
+ struct linux_dirent64 *dirp;
+ abi_long count = arg3;
+
+ dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
+ if (!dirp) {
+ goto efault;
+ }
+ ret = get_errno(sys_getdents64(arg1, dirp, count));
+ if (!is_error(ret)) {
+ /* Convert the dirent64 structs to target dirent. We do this
+ * in-place, since we can guarantee that a target_dirent is no
+ * larger than a dirent64; however this means we have to be
+ * careful to read everything before writing in the new format.
+ */
+ struct linux_dirent64 *de;
+ struct target_dirent *tde;
+ int len = ret;
+ int tlen = 0;
+
+ de = dirp;
+ tde = (struct target_dirent *)dirp;
+ while (len > 0) {
+ int namelen, treclen;
+ int reclen = de->d_reclen;
+ uint64_t ino = de->d_ino;
+ int64_t off = de->d_off;
+ uint8_t type = de->d_type;
+
+ namelen = strlen(de->d_name);
+ treclen = offsetof(struct target_dirent, d_name)
+ + namelen + 2;
+ treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
+
+ memmove(tde->d_name, de->d_name, namelen + 1);
+ tde->d_ino = tswapal(ino);
+ tde->d_off = tswapal(off);
+ tde->d_reclen = tswap16(treclen);
+ /* The target_dirent type is in what was formerly a padding
+ * byte at the end of the structure:
+ */
+ *(((char *)tde) + treclen - 1) = type;
+
+ de = (struct linux_dirent64 *)((char *)de + reclen);
+ tde = (struct target_dirent *)((char *)tde + treclen);
+ len -= reclen;
+ tlen += treclen;
+ }
+ ret = tlen;
+ }
+ unlock_user(dirp, arg2, ret);
+ }
+#endif
break;
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
case TARGET_NR_getdents64:
--
1.7.9.5
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v2] linux-user: Allow getdents to be provided by getdents64
2013-06-04 11:12 [Qemu-devel] [PATCH v2] linux-user: Allow getdents to be provided by getdents64 Peter Maydell
@ 2013-06-04 13:07 ` Richard Henderson
2013-06-05 10:57 ` Claudio Fontana
2013-06-05 11:18 ` Claudio Fontana
2 siblings, 0 replies; 5+ messages in thread
From: Richard Henderson @ 2013-06-04 13:07 UTC (permalink / raw)
To: Peter Maydell
Cc: Riku Voipio, Claudio Fontana, qemu-devel, patches, Laurent Vivier
On 06/04/2013 04:12 AM, Peter Maydell wrote:
> Newer architectures may only implement the getdents64 syscall, not
> getdents. Provide an implementation of getdents in terms of getdents64
> so that we can run getdents-using targets on a getdents64-only host.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Message-id: 1370193044-24535-1-git-send-email-peter.maydell@linaro.org
> ---
> Changes v1->v2:
> * memmove() call moved to before we write inode/offset/reclen
> * wrapped a stray long line that snuck in somehow
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v2] linux-user: Allow getdents to be provided by getdents64
2013-06-04 11:12 [Qemu-devel] [PATCH v2] linux-user: Allow getdents to be provided by getdents64 Peter Maydell
2013-06-04 13:07 ` Richard Henderson
@ 2013-06-05 10:57 ` Claudio Fontana
2013-06-05 11:08 ` Peter Maydell
2013-06-05 11:18 ` Claudio Fontana
2 siblings, 1 reply; 5+ messages in thread
From: Claudio Fontana @ 2013-06-05 10:57 UTC (permalink / raw)
To: Peter Maydell
Cc: Laurent Vivier, Richard Henderson, Riku Voipio, qemu-devel,
patches
On 04.06.2013 13:12, Peter Maydell wrote:
> Newer architectures may only implement the getdents64 syscall, not
> getdents. Provide an implementation of getdents in terms of getdents64
> so that we can run getdents-using targets on a getdents64-only host.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Message-id: 1370193044-24535-1-git-send-email-peter.maydell@linaro.org
> ---
> Changes v1->v2:
> * memmove() call moved to before we write inode/offset/reclen
> * wrapped a stray long line that snuck in somehow
>
> linux-user/syscall.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 60 insertions(+), 1 deletion(-)
>
I tested the change, and it works, however I get this during compilation:
linux-user/syscall.c:382:12: warning: 'sys_futimesat' defined but not used [-Wunused-function]
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 0099d64..4151c78 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -223,8 +223,11 @@ static int gettid(void) {
> return -ENOSYS;
> }
> #endif
> +#ifdef __NR_getdents
> _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
> -#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
> +#endif
> +#if !defined(__NR_getdents) || \
> + (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
> _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
> #endif
> #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
> @@ -7123,6 +7126,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
> break;
> #endif
> case TARGET_NR_getdents:
> +#ifdef __NR_getdents
> #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
> {
> struct target_dirent *target_dirp;
> @@ -7195,6 +7199,61 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
> unlock_user(dirp, arg2, ret);
> }
> #endif
> +#else
> + /* Implement getdents in terms of getdents64 */
> + {
> + struct linux_dirent64 *dirp;
> + abi_long count = arg3;
> +
> + dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
> + if (!dirp) {
> + goto efault;
> + }
> + ret = get_errno(sys_getdents64(arg1, dirp, count));
> + if (!is_error(ret)) {
> + /* Convert the dirent64 structs to target dirent. We do this
> + * in-place, since we can guarantee that a target_dirent is no
> + * larger than a dirent64; however this means we have to be
> + * careful to read everything before writing in the new format.
> + */
> + struct linux_dirent64 *de;
> + struct target_dirent *tde;
> + int len = ret;
> + int tlen = 0;
> +
> + de = dirp;
> + tde = (struct target_dirent *)dirp;
> + while (len > 0) {
> + int namelen, treclen;
> + int reclen = de->d_reclen;
> + uint64_t ino = de->d_ino;
> + int64_t off = de->d_off;
> + uint8_t type = de->d_type;
> +
> + namelen = strlen(de->d_name);
> + treclen = offsetof(struct target_dirent, d_name)
> + + namelen + 2;
> + treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
> +
> + memmove(tde->d_name, de->d_name, namelen + 1);
> + tde->d_ino = tswapal(ino);
> + tde->d_off = tswapal(off);
> + tde->d_reclen = tswap16(treclen);
> + /* The target_dirent type is in what was formerly a padding
> + * byte at the end of the structure:
> + */
> + *(((char *)tde) + treclen - 1) = type;
> +
> + de = (struct linux_dirent64 *)((char *)de + reclen);
> + tde = (struct target_dirent *)((char *)tde + treclen);
> + len -= reclen;
> + tlen += treclen;
> + }
> + ret = tlen;
> + }
> + unlock_user(dirp, arg2, ret);
> + }
> +#endif
> break;
> #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
> case TARGET_NR_getdents64:
>
--
Claudio Fontana
Server OS Architect
Huawei Technologies Duesseldorf GmbH
Riesstraße 25 - 80992 München
office: +49 89 158834 4135
mobile: +49 15253060158
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v2] linux-user: Allow getdents to be provided by getdents64
2013-06-05 10:57 ` Claudio Fontana
@ 2013-06-05 11:08 ` Peter Maydell
0 siblings, 0 replies; 5+ messages in thread
From: Peter Maydell @ 2013-06-05 11:08 UTC (permalink / raw)
To: Claudio Fontana
Cc: Laurent Vivier, Richard Henderson, Riku Voipio, qemu-devel,
patches
On 5 June 2013 11:57, Claudio Fontana <claudio.fontana@huawei.com> wrote:
> On 04.06.2013 13:12, Peter Maydell wrote:
>> Newer architectures may only implement the getdents64 syscall, not
>> getdents. Provide an implementation of getdents in terms of getdents64
>> so that we can run getdents-using targets on a getdents64-only host.
> I tested the change, and it works, however I get this during compilation:
>
> linux-user/syscall.c:382:12: warning: 'sys_futimesat' defined but not used [-Wunused-function]
That's a separate issue : for that you want this patch:
http://patchwork.ozlabs.org/patch/248092/
thanks
-- PMM
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v2] linux-user: Allow getdents to be provided by getdents64
2013-06-04 11:12 [Qemu-devel] [PATCH v2] linux-user: Allow getdents to be provided by getdents64 Peter Maydell
2013-06-04 13:07 ` Richard Henderson
2013-06-05 10:57 ` Claudio Fontana
@ 2013-06-05 11:18 ` Claudio Fontana
2 siblings, 0 replies; 5+ messages in thread
From: Claudio Fontana @ 2013-06-05 11:18 UTC (permalink / raw)
To: Peter Maydell
Cc: Laurent Vivier, Richard Henderson, Riku Voipio, qemu-devel,
patches
On 04.06.2013 13:12, Peter Maydell wrote:
> Newer architectures may only implement the getdents64 syscall, not
> getdents. Provide an implementation of getdents in terms of getdents64
> so that we can run getdents-using targets on a getdents64-only host.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Message-id: 1370193044-24535-1-git-send-email-peter.maydell@linaro.org
> ---
> Changes v1->v2:
> * memmove() call moved to before we write inode/offset/reclen
> * wrapped a stray long line that snuck in somehow
>
> linux-user/syscall.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 60 insertions(+), 1 deletion(-)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 0099d64..4151c78 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -223,8 +223,11 @@ static int gettid(void) {
> return -ENOSYS;
> }
> #endif
> +#ifdef __NR_getdents
> _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
> -#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
> +#endif
> +#if !defined(__NR_getdents) || \
> + (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
> _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
> #endif
> #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
> @@ -7123,6 +7126,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
> break;
> #endif
> case TARGET_NR_getdents:
> +#ifdef __NR_getdents
> #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
> {
> struct target_dirent *target_dirp;
> @@ -7195,6 +7199,61 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
> unlock_user(dirp, arg2, ret);
> }
> #endif
> +#else
> + /* Implement getdents in terms of getdents64 */
> + {
> + struct linux_dirent64 *dirp;
> + abi_long count = arg3;
> +
> + dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
> + if (!dirp) {
> + goto efault;
> + }
> + ret = get_errno(sys_getdents64(arg1, dirp, count));
> + if (!is_error(ret)) {
> + /* Convert the dirent64 structs to target dirent. We do this
> + * in-place, since we can guarantee that a target_dirent is no
> + * larger than a dirent64; however this means we have to be
> + * careful to read everything before writing in the new format.
> + */
> + struct linux_dirent64 *de;
> + struct target_dirent *tde;
> + int len = ret;
> + int tlen = 0;
> +
> + de = dirp;
> + tde = (struct target_dirent *)dirp;
> + while (len > 0) {
> + int namelen, treclen;
> + int reclen = de->d_reclen;
> + uint64_t ino = de->d_ino;
> + int64_t off = de->d_off;
> + uint8_t type = de->d_type;
> +
> + namelen = strlen(de->d_name);
> + treclen = offsetof(struct target_dirent, d_name)
> + + namelen + 2;
> + treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
> +
> + memmove(tde->d_name, de->d_name, namelen + 1);
> + tde->d_ino = tswapal(ino);
> + tde->d_off = tswapal(off);
> + tde->d_reclen = tswap16(treclen);
> + /* The target_dirent type is in what was formerly a padding
> + * byte at the end of the structure:
> + */
> + *(((char *)tde) + treclen - 1) = type;
> +
> + de = (struct linux_dirent64 *)((char *)de + reclen);
> + tde = (struct target_dirent *)((char *)tde + treclen);
> + len -= reclen;
> + tlen += treclen;
> + }
> + ret = tlen;
> + }
> + unlock_user(dirp, arg2, ret);
> + }
> +#endif
> break;
> #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
> case TARGET_NR_getdents64:
>
Tested on aarch64 Foundation v8
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-06-05 11:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-04 11:12 [Qemu-devel] [PATCH v2] linux-user: Allow getdents to be provided by getdents64 Peter Maydell
2013-06-04 13:07 ` Richard Henderson
2013-06-05 10:57 ` Claudio Fontana
2013-06-05 11:08 ` Peter Maydell
2013-06-05 11:18 ` Claudio Fontana
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).