[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] linux-user: Implement copy_file_range
From: |
Laurent Vivier |
Subject: |
Re: [PATCH] linux-user: Implement copy_file_range |
Date: |
Thu, 17 Dec 2020 12:13:10 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.5.0 |
Le 12/11/2020 à 12:45, Andreas Schwab a écrit :
> Signed-off-by: Andreas Schwab <schwab@suse.de>
> ---
> linux-user/syscall.c | 40 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 40 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 3160a9ba06..c3373af4c7 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -813,6 +813,12 @@ safe_syscall5(int, mq_timedsend, int, mqdes, const char
> *, msg_ptr,
> safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr,
> size_t, len, unsigned *, prio, const struct timespec *,
> timeout)
> #endif
> +#if defined(TARGET_NR_copy_file_range) && defined(__NR_copy_file_range)
> +safe_syscall6(ssize_t, copy_file_range, int, infd, loff_t *, pinoff,
> + int, outfd, loff_t *, poutoff, size_t, length,
> + unsigned int, flags)
> +#endif
> +
> /* We do ioctl like this rather than via safe_syscall3 to preserve the
> * "third argument might be integer or pointer or not present" behaviour of
> * the libc function.
> @@ -13057,6 +13063,40 @@ static abi_long do_syscall1(void *cpu_env, int num,
> abi_long arg1,
> return get_errno(membarrier(arg1, arg2));
> #endif
>
> +#if defined(TARGET_NR_copy_file_range) && defined(__NR_copy_file_range)
> + case TARGET_NR_copy_file_range:
> + {
> + loff_t inoff, outoff;
> + loff_t *pinoff = NULL, *poutoff = NULL;
> +
> + if (arg2) {
> + if (get_user_u64(inoff, arg2)) {
> + return -TARGET_EFAULT;
> + }
> + pinoff = &inoff;
> + }
> + if (arg4) {
> + if (get_user_u64(outoff, arg4)) {
> + return -TARGET_EFAULT;
> + }
> + poutoff = &outoff;
> + }
> + ret = get_errno(safe_copy_file_range(arg1, pinoff, arg3, poutoff,
> + arg5, arg6));
> + if (arg2) {
> + if (put_user_u64(inoff, arg2)) {
> + return -TARGET_EFAULT;
> + }
> + }
> + if (arg4) {
> + if (put_user_u64(outoff, arg4)) {
> + return -TARGET_EFAULT;
> + }
> + }
> + }
> + return ret;
> +#endif
> +
> default:
> qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
> return -TARGET_ENOSYS;
>
Applied to my branch linux-user-for-6.0, modified not to copy back offset when
there is an error.
Thanks,
Laurent