From patchwork Mon Dec 17 07:10:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Li Wang X-Patchwork-Id: 1014300 X-Patchwork-Delegate: petr.vorel@gmail.com 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=2001:1418:10:5::2; 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 [IPv6:2001:1418:10:5::2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43JC452T19z9sD9 for ; Mon, 17 Dec 2018 18:10:57 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 39BFD3E6EAF for ; Mon, 17 Dec 2018 08:10:51 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-4.smtp.seeweb.it (in-4.smtp.seeweb.it [IPv6:2001:4b78:1:20::4]) by picard.linux.it (Postfix) with ESMTP id 849143E6E6F for ; Mon, 17 Dec 2018 08:10:48 +0100 (CET) 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-4.smtp.seeweb.it (Postfix) with ESMTPS id 346311000C0A for ; Mon, 17 Dec 2018 08:10:46 +0100 (CET) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7564881DF1 for ; Mon, 17 Dec 2018 07:10:44 +0000 (UTC) Received: from dhcp-12-173.nay.redhat.com (dhcp-12-173.nay.redhat.com [10.66.12.173]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1211360BF1; Mon, 17 Dec 2018 07:10:42 +0000 (UTC) From: Li Wang To: ltp@lists.linux.it Date: Mon, 17 Dec 2018 15:10:38 +0800 Message-Id: <20181217071038.16255-1-liwang@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Mon, 17 Dec 2018 07:10:44 +0000 (UTC) X-Virus-Scanned: clamav-milter 0.99.2 at in-4.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-4.smtp.seeweb.it Cc: Miklos Szeredi , Ye Chao Subject: [LTP] [PATCH] fcntl: fcntl F_SETLEASE return EAGAIN on overlapfs 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" From Miklos's words: The F_SETLEASE "failure" is caused by the simplistic way the kernel currently determines if there's a possible local conflict to a write lock: check_conflicting_open(const struct dentry *dentry, const long arg, int flags) { /*...*/ if ((arg == F_WRLCK) && ((d_count(dentry) > 1) || (atomic_read(&inode->i_count) > 1))) ret = -EAGAIN; /*...*/ It reads the dentry count, and if there's any other reference to the dentry or inode as the one held by this file, then it is assumed to come from a conflicting open. Which is not true, dentry references can come from variety of sources (e.g. O_PATH opens are obviously non-conflicting). This causes failure on tmpfs as well, which holds an extra reference on each dentry. The extra ref on the dentry in overlayfs comes from the realfile stored in the overlay file's private_data field. The proper solution to this is probably to have an i_readcount, matching the functionality of i_writecount, which would solve the other problems with the current approach. Note: this is not a failure in the sense that applications must be written with the assumption that F_SETLEASE can fail with -EAGAIN, so this error condition just makes the lease non-useful, but shouldn't break anything. Reviewed-by: Petr Vorel ==== Error log ===== fcntl24 1 TFAIL : fcntl24.c:148: fcntl(tfile_7254, F_SETLEASE, F_WRLCK) Failed, errno=11 : Resource temporarily unavailable fcntl25 1 TFAIL : fcntl25.c:149: fcntl(tfile_7255, F_SETLEASE, F_WRLCK) Failed, errno=11 : Resource temporarily unavailable fcntl26 1 TFAIL : fcntl26.c:149: fcntl(tfile_7256, F_SETLEASE, F_WRLCK) Failed, errno=11 : Resource temporarily unavailable fcntl33.c:118: FAIL: fcntl() failed to set lease: EAGAIN/EWOULDBLOCK fcntl33.c:118: FAIL: fcntl() failed to set lease: EAGAIN/EWOULDBLOCK fcntl33.c:118: FAIL: fcntl() failed to set lease: EAGAIN/EWOULDBLOCK fcntl33.c:118: FAIL: fcntl() failed to set lease: EAGAIN/EWOULDBLOCK Reported-by: Xiong Zhou Signed-off-by: Li Wang Cc: Miklos Szeredi Cc: Ye Chao --- include/tst_fs.h | 1 + lib/tst_fs_type.c | 2 ++ testcases/kernel/syscalls/fcntl/fcntl24.c | 12 +++++++++--- testcases/kernel/syscalls/fcntl/fcntl25.c | 12 +++++++++--- testcases/kernel/syscalls/fcntl/fcntl26.c | 12 +++++++++--- testcases/kernel/syscalls/fcntl/fcntl33.c | 8 +++++++- 6 files changed, 37 insertions(+), 10 deletions(-) diff --git a/include/tst_fs.h b/include/tst_fs.h index 8d3f1cfbc..23f139ded 100644 --- a/include/tst_fs.h +++ b/include/tst_fs.h @@ -41,6 +41,7 @@ #define TST_F2FS_MAGIC 0xF2F52010 #define TST_NILFS_MAGIC 0x3434 #define TST_EXOFS_MAGIC 0x5DF5 +#define TST_OVERLAYFS_MAGIC 0x794c7630 enum { TST_BYTES = 1, diff --git a/lib/tst_fs_type.c b/lib/tst_fs_type.c index 5fbf0f436..1d0ac9669 100644 --- a/lib/tst_fs_type.c +++ b/lib/tst_fs_type.c @@ -82,6 +82,8 @@ const char *tst_fs_type_name(long f_type) return "NILFS"; case TST_EXOFS_MAGIC: return "EXOFS"; + case TST_OVERLAYFS_MAGIC: + return "OVERLAYFS"; default: return "Unknown"; } diff --git a/testcases/kernel/syscalls/fcntl/fcntl24.c b/testcases/kernel/syscalls/fcntl/fcntl24.c index 4711d52ff..167f245c4 100644 --- a/testcases/kernel/syscalls/fcntl/fcntl24.c +++ b/testcases/kernel/syscalls/fcntl/fcntl24.c @@ -143,9 +143,15 @@ int main(int ac, char **av) /* check return code */ if (TEST_RETURN == -1) { - tst_resm(TFAIL, - "fcntl(%s, F_SETLEASE, F_WRLCK) Failed, errno=%d : %s", - fname, TEST_ERRNO, strerror(TEST_ERRNO)); + if (type == TST_OVERLAYFS_MAGIC && TEST_ERRNO == EAGAIN) { + tst_resm(TINFO | TTERRNO, + "fcntl(F_SETLEASE, F_WRLCK) " + "failed on overlapfs as expected"); + } else { + tst_resm(TFAIL, + "fcntl(%s, F_SETLEASE, F_WRLCK) Failed, errno=%d : %s", + fname, TEST_ERRNO, strerror(TEST_ERRNO)); + } } else { TEST(fcntl(fd, F_GETLEASE)); if (TEST_RETURN != F_WRLCK) diff --git a/testcases/kernel/syscalls/fcntl/fcntl25.c b/testcases/kernel/syscalls/fcntl/fcntl25.c index bf6dd1da5..052530c3c 100644 --- a/testcases/kernel/syscalls/fcntl/fcntl25.c +++ b/testcases/kernel/syscalls/fcntl/fcntl25.c @@ -144,9 +144,15 @@ int main(int ac, char **av) /* check return code */ if (TEST_RETURN == -1) { - tst_resm(TFAIL, - "fcntl(%s, F_SETLEASE, F_WRLCK) Failed, errno=%d : %s", - fname, TEST_ERRNO, strerror(TEST_ERRNO)); + if (type == TST_OVERLAYFS_MAGIC && TEST_ERRNO == EAGAIN) { + tst_resm(TINFO | TTERRNO, + "fcntl(F_SETLEASE, F_WRLCK) " + "failed on overlapfs as expected"); + } else { + tst_resm(TFAIL, + "fcntl(%s, F_SETLEASE, F_WRLCK) Failed, errno=%d : %s", + fname, TEST_ERRNO, strerror(TEST_ERRNO)); + } } else { TEST(fcntl(fd, F_GETLEASE)); if (TEST_RETURN != F_WRLCK) diff --git a/testcases/kernel/syscalls/fcntl/fcntl26.c b/testcases/kernel/syscalls/fcntl/fcntl26.c index 8c2591b9f..b74c6a7a9 100644 --- a/testcases/kernel/syscalls/fcntl/fcntl26.c +++ b/testcases/kernel/syscalls/fcntl/fcntl26.c @@ -144,9 +144,15 @@ int main(int ac, char **av) /* check return code */ if (TEST_RETURN == -1) { - tst_resm(TFAIL, - "fcntl(%s, F_SETLEASE, F_WRLCK) Failed, errno=%d : %s", - fname, TEST_ERRNO, strerror(TEST_ERRNO)); + if (type == TST_OVERLAYFS_MAGIC && TEST_ERRNO == EAGAIN) { + tst_resm(TINFO | TTERRNO, + "fcntl(F_SETLEASE, F_WRLCK) " + "failed on overlapfs as expected"); + } else { + tst_resm(TFAIL, + "fcntl(%s, F_SETLEASE, F_WRLCK) Failed, errno=%d : %s", + fname, TEST_ERRNO, strerror(TEST_ERRNO)); + } } else { TEST(fcntl(fd, F_GETLEASE)); if (TEST_RETURN != F_WRLCK) diff --git a/testcases/kernel/syscalls/fcntl/fcntl33.c b/testcases/kernel/syscalls/fcntl/fcntl33.c index ca7a796bf..9dd8b0721 100644 --- a/testcases/kernel/syscalls/fcntl/fcntl33.c +++ b/testcases/kernel/syscalls/fcntl/fcntl33.c @@ -115,7 +115,13 @@ static void do_test(unsigned int i) TEST(fcntl(fd, F_SETLEASE, test_cases[i].lease_type)); if (TST_RET == -1) { - tst_res(TFAIL | TTERRNO, "fcntl() failed to set lease"); + if (type == TST_OVERLAYFS_MAGIC && TST_ERR == EAGAIN) { + tst_res(TINFO | TTERRNO, + "fcntl(F_SETLEASE, F_WRLCK) " + "failed on overlapfs as expected"); + } else { + tst_res(TFAIL | TTERRNO, "fcntl() failed to set lease"); + } goto exit; }