From patchwork Mon Sep 17 08:53:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Stancek X-Patchwork-Id: 970464 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42DKg439zVz9sBv for ; Mon, 17 Sep 2018 18:54:08 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id AF37F3E609C for ; Mon, 17 Sep 2018 10:54:05 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-2.smtp.seeweb.it (in-2.smtp.seeweb.it [217.194.8.2]) by picard.linux.it (Postfix) with ESMTP id AA5633E6076 for ; Mon, 17 Sep 2018 10:54:03 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by in-2.smtp.seeweb.it (Postfix) with ESMTPS id 2B3426001FA for ; Mon, 17 Sep 2018 10:54:01 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 81C4CA459D; Mon, 17 Sep 2018 08:53:59 +0000 (UTC) Received: from dustball.brq.redhat.com (unknown [10.43.17.9]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9945118148; Mon, 17 Sep 2018 08:53:58 +0000 (UTC) From: Jan Stancek To: ltp@lists.linux.it Date: Mon, 17 Sep 2018 10:53:55 +0200 Message-Id: <20d04a28a6254edd95f0bee0e3662c147603665b.1537174128.git.jstancek@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 17 Sep 2018 08:53:59 +0000 (UTC) X-Virus-Scanned: clamav-milter 0.99.2 at in-2.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=-0.0 required=7.0 tests=SPF_HELO_PASS,SPF_PASS autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-2.smtp.seeweb.it Cc: yuriy.kolerov@synopsys.com Subject: [LTP] [PATCH] syscalls/fcntl: make OFD commands use fcntl64() syscall on 32-bit X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" OFD commands require 64-bit argument (struct flock64). Until glibc commit 06ab719d30b0 ("Fix Linux fcntl OFD locks for non-LFS architectures (BZ#20251)") we relied on glibc passing arg directly to syscall. This creates problem for 32-bit version of the test, because old glibc is passing arg directly, while new one is casting it to struct flock. We could add a configure check for glibc version, but that may not help with other libc libraries. We could do a runtime check that exploits non-zero l_pid returning EINVAL. This however complicates SAFE_FCNTL macro substantially. This patch changes 32-bit version of test to use syscall directly. Signed-off-by: Jan Stancek --- testcases/kernel/syscalls/fcntl/fcntl34.c | 10 ++++++-- testcases/kernel/syscalls/fcntl/fcntl36.c | 19 +++++++++++---- testcases/kernel/syscalls/fcntl/fcntl_common.h | 33 ++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 testcases/kernel/syscalls/fcntl/fcntl_common.h diff --git a/testcases/kernel/syscalls/fcntl/fcntl34.c b/testcases/kernel/syscalls/fcntl/fcntl34.c index aa29cf9ea0d8..90c40f9cf4c6 100644 --- a/testcases/kernel/syscalls/fcntl/fcntl34.c +++ b/testcases/kernel/syscalls/fcntl/fcntl34.c @@ -28,6 +28,7 @@ #include "lapi/fcntl.h" #include "tst_safe_pthread.h" #include "tst_test.h" +#include "fcntl_common.h" static int thread_cnt; static const int max_thread_cnt = 32; @@ -68,7 +69,12 @@ void *thread_fn_01(void *arg) memset(buf, (intptr_t)arg, write_size); +/* see explanation in fcntl_common.h */ +#ifdef USE_STRUCT_FLOCK64 struct flock64 lck = { +#else + struct flock lck = { +#endif .l_whence = SEEK_SET, .l_start = 0, .l_len = 1, @@ -76,13 +82,13 @@ void *thread_fn_01(void *arg) for (i = 0; i < writes_num; ++i) { lck.l_type = F_WRLCK; - SAFE_FCNTL(fd, F_OFD_SETLKW, &lck); + my_fcntl(fd, F_OFD_SETLKW, &lck); SAFE_LSEEK(fd, 0, SEEK_END); SAFE_WRITE(1, fd, buf, write_size); lck.l_type = F_UNLCK; - SAFE_FCNTL(fd, F_OFD_SETLKW, &lck); + my_fcntl(fd, F_OFD_SETLKW, &lck); sched_yield(); } diff --git a/testcases/kernel/syscalls/fcntl/fcntl36.c b/testcases/kernel/syscalls/fcntl/fcntl36.c index 81bd5a647e4c..709fcd3a6239 100644 --- a/testcases/kernel/syscalls/fcntl/fcntl36.c +++ b/testcases/kernel/syscalls/fcntl/fcntl36.c @@ -57,6 +57,7 @@ #include "lapi/fcntl.h" #include "tst_safe_pthread.h" #include "tst_test.h" +#include "fcntl_common.h" static int thread_cnt; static int fail_flag = 0; @@ -87,7 +88,12 @@ static void *fn_ofd_w(void *arg) int fd = SAFE_OPEN(fname, O_RDWR); long wt = pa->cnt; +/* see explanation in fcntl_common.h */ +#ifdef USE_STRUCT_FLOCK64 struct flock64 lck = { +#else + struct flock lck = { +#endif .l_whence = SEEK_SET, .l_start = pa->offset, .l_len = pa->length, @@ -99,13 +105,13 @@ static void *fn_ofd_w(void *arg) memset(buf, wt, pa->length); lck.l_type = F_WRLCK; - SAFE_FCNTL(fd, F_OFD_SETLKW, &lck); + my_fcntl(fd, F_OFD_SETLKW, &lck); SAFE_LSEEK(fd, pa->offset, SEEK_SET); SAFE_WRITE(1, fd, buf, pa->length); lck.l_type = F_UNLCK; - SAFE_FCNTL(fd, F_OFD_SETLKW, &lck); + my_fcntl(fd, F_OFD_SETLKW, &lck); wt++; if (wt >= 255) @@ -166,7 +172,12 @@ static void *fn_ofd_r(void *arg) int i; int fd = SAFE_OPEN(fname, O_RDWR); +/* see explanation in fcntl_common.h */ +#ifdef USE_STRUCT_FLOCK64 struct flock64 lck = { +#else + struct flock lck = { +#endif .l_whence = SEEK_SET, .l_start = pa->offset, .l_len = pa->length, @@ -178,7 +189,7 @@ static void *fn_ofd_r(void *arg) memset(buf, 0, pa->length); lck.l_type = F_RDLCK; - SAFE_FCNTL(fd, F_OFD_SETLKW, &lck); + my_fcntl(fd, F_OFD_SETLKW, &lck); /* rlock acquired */ SAFE_LSEEK(fd, pa->offset, SEEK_SET); @@ -209,7 +220,7 @@ static void *fn_ofd_r(void *arg) } lck.l_type = F_UNLCK; - SAFE_FCNTL(fd, F_OFD_SETLK, &lck); + my_fcntl(fd, F_OFD_SETLK, &lck); sched_yield(); } diff --git a/testcases/kernel/syscalls/fcntl/fcntl_common.h b/testcases/kernel/syscalls/fcntl/fcntl_common.h new file mode 100644 index 000000000000..d73e4624f3f6 --- /dev/null +++ b/testcases/kernel/syscalls/fcntl/fcntl_common.h @@ -0,0 +1,33 @@ +#include "lapi/syscalls.h" + +/* + * glibc commit: + * 06ab719d30b0 ("Fix Linux fcntl OFD locks for non-LFS architectures (BZ#20251)") + * changed behavior of arg parameter for OFD commands. It is no + * longer passing arg directly to syscall, but expects it to be + * 'struct flock'. + * + * On 64-bit or _FILE_OFFSET_BITS == 64 we can use fcntl() and + * struct flock with any glibc version. struct flock and flock64 + * should be identical. + * + * On 32-bit, older glibc would pass arg directly, recent one treats + * it as 'struct flock' and converts it to 'struct flock64'. + * So, to support both version, on 32-bit we use fcntl64 syscall + * directly with struct flock64. + */ +#if __WORDSIZE == 64 || _FILE_OFFSET_BITS == 64 +static int my_fcntl(int fd, int cmd, void *lck) +{ + return SAFE_FCNTL(fd, cmd, lck); +} +#else +#define USE_STRUCT_FLOCK64 +static int my_fcntl(int fd, int cmd, void *lck) +{ + int ret = tst_syscall(__NR_fcntl64, fd, cmd, lck); + if (ret == -1) + tst_brk(TBROK|TERRNO, "fcntl64"); + return ret; +} +#endif