From patchwork Wed Jul 6 19:52:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 71486 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp1042499qgy; Wed, 6 Jul 2016 12:53:06 -0700 (PDT) X-Received: by 10.66.62.169 with SMTP id z9mr31734379par.137.1467834786141; Wed, 06 Jul 2016 12:53:06 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id h2si5283546pax.194.2016.07.06.12.53.05 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Jul 2016 12:53:06 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-71579-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of libc-alpha-return-71579-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-71579-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; q=dns; s= default; b=E/TpWCvjIPCp35y64TL+fEnREplwZKz/aB58RwOjHV4vBfUqmdc36 Cdn6Ye2CsGFvetC+gX0SFN/pz7Uf7urEf91id4zq24OdmJBNL975HIdc6BENSL2b 1hVtuulWXU7h5h7vE02FlvGecQJVRr42iZcjA5wln6YHdVR7teUBbs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; s=default; bh=tyZ0sEcZj8FRwsS9xnpopnGYOhU=; b=J5uo9w/cMm3aonWbqu8MwYTEAMEL smKv+Ciibvno3YNs4AUmR+zgIfg88C5/htr/2lm6L4zmdlbR7JFozrbLPk7ZuMxq FpA2Nrr6SuQGpZku18EBTajWqZeYn5wJ+TrM+1IJ703o2bPFRttLLrPVuBPhEf9Q Gwui2qD++8r022s= Received: (qmail 95548 invoked by alias); 6 Jul 2016 19:52:57 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 95532 invoked by uid 89); 6 Jul 2016 19:52:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=buf1, buffers X-HELO: mail-yw0-f177.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=C9Uh0uJGQ0YBL9Sqxjbz6rj6hUY062Ftj7+KMRCV11A=; b=Svw2PTKWWyRjpXe+Vk9Y05RVdZQFerU5b1CXzU4qM/r/mGXLur67HdMcaGJ5dHVzcY KwHE+pTLSzc5HSv/ulXnbqHDvk1XGpduowqdN7eE1c+eDfUIjzX3ty/ksUJGLwI3BmYa PgKwGqHpB0EGAUIW8vZGGLXv2KVUElzsjqoE+iBInvSbKeIOumT4Bt4I0nD/vqaDuSzP xUsun2+z9HnhrltFxDMYG4mwfhK21G4MrdO4xw3/QQJCp5rPZ/jRu/pPQ3qLYVRXAIvH tOQqOInsANuvE+a7GmFl6QUcWK4CtpwkOSf+HvO7QHpkkEx+0aaheTmBTvMN4KKDcncX AtrA== X-Gm-Message-State: ALyK8tKToRN+AK3Ka/4JilFW5CE2J4SpzywdVzKA9e37V7FummHYDfJt+RHm92xhNz3RWFUv X-Received: by 10.129.154.202 with SMTP id r193mr10510995ywg.164.1467834763897; Wed, 06 Jul 2016 12:52:43 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2] Fix LO_HI_LONG definition Date: Wed, 6 Jul 2016 16:52:36 -0300 Message-Id: <1467834756-21898-1-git-send-email-adhemerval.zanella@linaro.org> The p{read,write}v{64} consolidation patch [1] added a wrong guard for LO_HI_LONG definition. It currently uses both '__WORDSIZE == 64' and 'defined __ASSUME_WORDSIZE64_ILP32' to set the value to be passed in one argument, otherwise it will be split in two. Since kernel commit 601cc11d054 the non-compat preadv/pwritev in same order, so the LO_HI_LONG is the same regardless off/off64_t size or wordsize. The tests were passing on 64-bit because files were small enough so the high part of offset is 0 regardless. This patch also changes the tst-preadvwritev64 test to check reads and writes on a sparse file larger than 4G. Checked on x86_64, i686, x32, aarch64, armhf, and s390. * sysdeps/unix/sysv/linux/sysdep.h [__WORDSIZE == 64 || __ASSUME_WORDSIZE64_ILP32] (LO_HI_LONG): Remove guards. * misc/tst-preadvwritev-common.c: New file. * misc/tst-preadvwritev.c: Use tst-preadvwritev-common.c. * misc/tst-preadvwritev64.c: Use tst-preadwritev-common.c and add a check for files larger than 2GB. [1] 4751bbe2ad4d1bfa05774e29376d553ecfe563b0 --- ChangeLog | 8 +++ misc/tst-preadvwritev-common.c | 112 +++++++++++++++++++++++++++++++++++++++ misc/tst-preadvwritev.c | 93 +------------------------------- misc/tst-preadvwritev64.c | 26 +++++++-- sysdeps/unix/sysv/linux/sysdep.h | 10 ++-- 5 files changed, 148 insertions(+), 101 deletions(-) create mode 100644 misc/tst-preadvwritev-common.c -- 2.7.4 diff --git a/misc/tst-preadvwritev-common.c b/misc/tst-preadvwritev-common.c new file mode 100644 index 0000000..9a66a5f --- /dev/null +++ b/misc/tst-preadvwritev-common.c @@ -0,0 +1,112 @@ +/* Common definitions for preadv and pwritev. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include "test-skeleton.c" + +static char *temp_filename; +static int temp_fd; + +static void +do_prepare (void) +{ + temp_fd = create_temp_file ("tst-preadvwritev.", &temp_filename); + if (temp_fd == -1) + { + printf ("cannot create temporary file: %m\n"); + exit (1); + } +} + +#define FAIL(str) \ + do { printf ("error: %s (line %d)\n", str, __LINE__); return 1; } while (0) + +static int +do_test_with_offset (off_t offset) +{ + struct iovec iov[2]; + ssize_t ret; + + char buf1[32]; + char buf2[64]; + + memset (buf1, 0xf0, sizeof buf1); + memset (buf2, 0x0f, sizeof buf2); + + /* Write two buffer with 32 and 64 bytes respectively. */ + memset (iov, 0, sizeof iov); + iov[0].iov_base = buf1; + iov[0].iov_len = sizeof buf1; + iov[1].iov_base = buf2; + iov[1].iov_len = sizeof buf2; + + ret = pwritev (temp_fd, iov, 2, offset); + if (ret == -1) + FAIL ("first pwritev returned -1"); + if (ret != (sizeof buf1 + sizeof buf2)) + FAIL ("first pwritev returned an unexpected value"); + + ret = pwritev (temp_fd, iov, 2, sizeof buf1 + sizeof buf2 + offset); + if (ret == -1) + FAIL ("second pwritev returned -1"); + if (ret != (sizeof buf1 + sizeof buf2)) + FAIL ("second pwritev returned an unexpected value"); + + char buf3[32]; + char buf4[64]; + + memset (buf3, 0x0f, sizeof buf3); + memset (buf4, 0xf0, sizeof buf4); + + iov[0].iov_base = buf3; + iov[0].iov_len = sizeof buf3; + iov[1].iov_base = buf4; + iov[1].iov_len = sizeof buf4; + + /* Now read two buffer with 32 and 64 bytes respectively. */ + ret = preadv (temp_fd, iov, 2, offset); + if (ret == -1) + FAIL ("first preadv returned -1"); + if (ret != (sizeof buf3 + sizeof buf4)) + FAIL ("first preadv returned an unexpected value"); + + if (memcmp (buf1, buf3, sizeof buf1) != 0) + FAIL ("first buffer from first preadv different than expected"); + if (memcmp (buf2, buf4, sizeof buf2) != 0) + FAIL ("second buffer from first preadv different than expected"); + + ret = preadv (temp_fd, iov, 2, sizeof buf3 + sizeof buf4 + offset); + if (ret == -1) + FAIL ("second preadv returned -1"); + if (ret != (sizeof buf3 + sizeof buf4)) + FAIL ("second preadv returned an unexpected value"); + + /* And compare the buffers read and written to check if there are equal. */ + if (memcmp (buf1, buf3, sizeof buf1) != 0) + FAIL ("first buffer from second preadv different than expected"); + if (memcmp (buf2, buf4, sizeof buf2) != 0) + FAIL ("second buffer from second preadv different than expected"); + + return 0; +} + diff --git a/misc/tst-preadvwritev.c b/misc/tst-preadvwritev.c index 08deecc..50a80a7 100644 --- a/misc/tst-preadvwritev.c +++ b/misc/tst-preadvwritev.c @@ -16,99 +16,10 @@ License along with the GNU C Library; if not, see . */ -#include - -/* Allow testing of the 64-bit versions as well. */ -#ifndef PREADV -# define PREADV preadv -# define PWRITEV pwritev -#endif - -static void do_prepare (void); -static int do_test (void); -#define PREPARE(argc, argv) do_prepare () -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" - -static char *temp_filename; -static int temp_fd; - -void -do_prepare (void) -{ - temp_fd = create_temp_file ("tst-PREADVwritev.", &temp_filename); - if (temp_fd == -1) - { - printf ("cannot create temporary file: %m\n"); - exit (1); - } -} - -#define FAIL(str) \ - do { printf ("error: %s (line %d)\n", str, __LINE__); return 1; } while (0) +#include "tst-preadvwritev-common.c" int do_test (void) { - struct iovec iov[2]; - ssize_t ret; - - char buf1[32]; - char buf2[64]; - - memset (buf1, 0xf0, sizeof buf1); - memset (buf2, 0x0f, sizeof buf2); - - memset (iov, 0, sizeof iov); - iov[0].iov_base = buf1; - iov[0].iov_len = sizeof buf1; - iov[1].iov_base = buf2; - iov[1].iov_len = sizeof buf2; - - ret = PWRITEV (temp_fd, iov, 2, 0); - if (ret == -1) - FAIL ("first PWRITEV returned -1"); - if (ret != (sizeof buf1 + sizeof buf2)) - FAIL ("first PWRITEV returned an unexpected value"); - - ret = PWRITEV (temp_fd, iov, 2, sizeof buf1 + sizeof buf2); - if (ret == -1) - FAIL ("second PWRITEV returned -1"); - if (ret != (sizeof buf1 + sizeof buf2)) - FAIL ("second PWRITEV returned an unexpected value"); - - char buf3[32]; - char buf4[64]; - - memset (buf3, 0x0f, sizeof buf3); - memset (buf4, 0xf0, sizeof buf4); - - iov[0].iov_base = buf3; - iov[0].iov_len = sizeof buf3; - iov[1].iov_base = buf4; - iov[1].iov_len = sizeof buf4; - - ret = PREADV (temp_fd, iov, 2, 0); - if (ret == -1) - FAIL ("first PREADV returned -1"); - if (ret != (sizeof buf3 + sizeof buf4)) - FAIL ("first PREADV returned an unexpected value"); - - if (memcmp (buf1, buf3, sizeof buf1) != 0) - FAIL ("first buffer from first PREADV different than expected"); - if (memcmp (buf2, buf4, sizeof buf2) != 0) - FAIL ("second buffer from first PREADV different than expected"); - - ret = PREADV (temp_fd, iov, 2, sizeof buf3 + sizeof buf4); - if (ret == -1) - FAIL ("second PREADV returned -1"); - if (ret != (sizeof buf3 + sizeof buf4)) - FAIL ("second PREADV returned an unexpected value"); - - if (memcmp (buf1, buf3, sizeof buf1) != 0) - FAIL ("first buffer from second PREADV different than expected"); - if (memcmp (buf2, buf4, sizeof buf2) != 0) - FAIL ("second buffer from second PREADV different than expected"); - - return 0; + return do_test_with_offset (0); } diff --git a/misc/tst-preadvwritev64.c b/misc/tst-preadvwritev64.c index ff6e134..0e1f341 100644 --- a/misc/tst-preadvwritev64.c +++ b/misc/tst-preadvwritev64.c @@ -16,7 +16,27 @@ License along with the GNU C Library; if not, see . */ -#define PREADV preadv64 -#define PWRITEV pwritev64 +#define _FILE_OFFSET_BITS 64 +#include "tst-preadvwritev-common.c" -#include "tst-preadvwritev.c" +int +do_test (void) +{ + int ret; + + ret = do_test_with_offset (0); + + /* Create a sparse file larger than 4GB to check if offset is handled + correctly in p{write,read}v64. */ + off_t base_offset = UINT32_MAX; + off_t fsize = base_offset + 2048; + if (ftruncate (temp_fd, fsize) != 0) + { + printf ("error: ftruncate (%jd) failed: %m", (intmax_t) fsize); + return 1; + } + + ret += do_test_with_offset (base_offset); + + return ret; +} diff --git a/sysdeps/unix/sysv/linux/sysdep.h b/sysdeps/unix/sysv/linux/sysdep.h index 8c9e62e..a469f57 100644 --- a/sysdeps/unix/sysv/linux/sysdep.h +++ b/sysdeps/unix/sysv/linux/sysdep.h @@ -49,10 +49,6 @@ #endif /* Provide a macro to pass the off{64}_t argument on p{readv,writev}{64}. */ -#if __WORDSIZE == 64 || defined __ASSUME_WORDSIZE64_ILP32 -# define LO_HI_LONG(val) (val) -#else -# define LO_HI_LONG(val) \ - (long) (val), \ - (long) (((uint64_t) (val)) >> 32) -#endif +#define LO_HI_LONG(val) \ + (long) (val), \ + (long) (((uint64_t) (val)) >> 32)