From patchwork Tue Jun 4 11:12:57 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 17498 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ve0-f200.google.com (mail-ve0-f200.google.com [209.85.128.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 75FF72390D for ; Tue, 4 Jun 2013 11:13:04 +0000 (UTC) Received: by mail-ve0-f200.google.com with SMTP id m1sf76625ves.3 for ; Tue, 04 Jun 2013 04:13:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-beenthere:x-forwarded-to:x-forwarded-for :delivered-to:from:to:cc:subject:date:message-id:x-mailer :x-gm-message-state:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-google-group-id:list-post:list-help:list-archive:list-unsubscribe; bh=69xRVLZoEtH15XHkgXm790VVAeImW8USz/fXjBv5+XI=; b=EHobV053JxC754yQNlfBdg9wOR8+Cp8mZ1/UAqcJ7b8OJWtaXujWz7R0VvMPorwULV z0axwrwZOVTuogrdQUxeLVdDPZWhRQpCmdN+C3rmaTCv7AACyTSf4Y89V8SLBUShjkDh 793lU1qoMTW7gXdAlwd5s0mluqmMwhFTsCKKCzUmKkBBIo1JkWoeVei2e5EhMP9pOkpB H40aHRYQzj+V8CSMtLL60p1zI66NiujS6br2Y08D8EJU5R+JkboJl5ntGj32b0RcJpoE MAw7m237YeLWa715t2+rweOEYXaaabiNVE/aaA+GPVS4/9klUL1/scVFPooTrTT7Qddw X4nA== X-Received: by 10.224.42.141 with SMTP id s13mr16235578qae.3.1370344383529; Tue, 04 Jun 2013 04:13:03 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.76.65 with SMTP id i1ls214456qew.2.gmail; Tue, 04 Jun 2013 04:13:03 -0700 (PDT) X-Received: by 10.58.75.73 with SMTP id a9mr18661107vew.25.1370344383191; Tue, 04 Jun 2013 04:13:03 -0700 (PDT) Received: from mail-vb0-x22f.google.com (mail-vb0-x22f.google.com [2607:f8b0:400c:c02::22f]) by mx.google.com with ESMTPS id ha8si37313865vdb.100.2013.06.04.04.13.03 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 04 Jun 2013 04:13:03 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c02::22f is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c02::22f; Received: by mail-vb0-f47.google.com with SMTP id x14so41887vbb.20 for ; Tue, 04 Jun 2013 04:13:03 -0700 (PDT) X-Received: by 10.52.155.67 with SMTP id vu3mr15667469vdb.94.1370344382995; Tue, 04 Jun 2013 04:13:02 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.221.10.206 with SMTP id pb14csp119981vcb; Tue, 4 Jun 2013 04:13:02 -0700 (PDT) X-Received: by 10.180.79.69 with SMTP id h5mr942732wix.14.1370344381772; Tue, 04 Jun 2013 04:13:01 -0700 (PDT) Received: from mnementh.archaic.org.uk (1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id bf3si22036853wjb.33.2013.06.04.04.13.01 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 04 Jun 2013 04:13:01 -0700 (PDT) Received-SPF: neutral (google.com: 2001:8b0:1d0::1 is neither permitted nor denied by best guess record for domain of pm215@archaic.org.uk) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1UjpAf-000796-8l; Tue, 04 Jun 2013 12:12:57 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Riku Voipio , Claudio Fontana , Laurent Vivier , Richard Henderson Subject: [PATCH v2] linux-user: Allow getdents to be provided by getdents64 Date: Tue, 4 Jun 2013 12:12:57 +0100 Message-Id: <1370344377-27445-1-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 X-Gm-Message-State: ALoCoQlt4B6Lgp/U006rUamInKY1tgiYW6yZm7aXhJ7jB9ZLg8zJ9QrQTrJoARKEgRuN9TdaButF X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c02::22f is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , 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 Message-id: 1370193044-24535-1-git-send-email-peter.maydell@linaro.org Reviewed-by: Richard Henderson Tested-by: Claudio Fontana --- 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: