From patchwork Wed Jul 17 09:44:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Xu X-Patchwork-Id: 1133217 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=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=none (p=none dis=none) header.from=cn.fujitsu.com Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45pXSD3LzQz9sBF for ; Wed, 17 Jul 2019 19:45:15 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id C56AC3C1D28 for ; Wed, 17 Jul 2019 11:45:12 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-3.smtp.seeweb.it (in-3.smtp.seeweb.it [IPv6:2001:4b78:1:20::3]) by picard.linux.it (Postfix) with ESMTP id 7DBEF3C1CA0 for ; Wed, 17 Jul 2019 11:45:10 +0200 (CEST) Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by in-3.smtp.seeweb.it (Postfix) with ESMTP id 648971A00934 for ; Wed, 17 Jul 2019 11:45:07 +0200 (CEST) X-IronPort-AV: E=Sophos;i="5.64,273,1559491200"; d="scan'208";a="71629079" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 17 Jul 2019 17:45:04 +0800 Received: from G08CNEXCHPEKD02.g08.fujitsu.local (unknown [10.167.33.83]) by cn.fujitsu.com (Postfix) with ESMTP id 49F7F4CDDD42; Wed, 17 Jul 2019 17:45:01 +0800 (CST) Received: from localhost.localdomain (10.167.215.46) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 17 Jul 2019 17:45:05 +0800 From: Yang Xu To: Date: Wed, 17 Jul 2019 17:44:34 +0800 Message-ID: <1563356676-2384-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <20190711125108.GB8709@rei> References: <20190711125108.GB8709@rei> MIME-Version: 1.0 X-Originating-IP: [10.167.215.46] X-yoursite-MailScanner-ID: 49F7F4CDDD42.AFF8E X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: xuyang2018.jy@cn.fujitsu.com X-Spam-Status: No, score=0.0 required=7.0 tests=SPF_HELO_NONE,SPF_NONE autolearn=disabled version=3.4.0 X-Virus-Scanned: clamav-milter 0.99.2 at in-3.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-3.smtp.seeweb.it Subject: [LTP] [PATCH v5 1/3] lib: alter find_free_loopdev() X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ltp@lists.linux.it Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" Alter find_free_loopdev() to tst_find_free_loopdev(path, path_len), it passes the dev_path inside of the tst_device.c and NULL from other tests. It returns the free loopdev minor (and -1 for no free loopdev). We can call tst_find_free_loopdev(NULL, 0) to get a free minor number without changing lib internal state. Signed-off-by: Yang Xu Reviewed-by: Amir Goldstein --- doc/test-writing-guidelines.txt | 12 ++++++++++++ include/tst_device.h | 5 +++++ lib/tst_device.c | 34 +++++++++++++++++---------------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt index 4b1e7d25b..c65c707e6 100644 --- a/doc/test-writing-guidelines.txt +++ b/doc/test-writing-guidelines.txt @@ -1045,6 +1045,18 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to ------------------------------------------------------------------------------- #include "tst_test.h" +int tst_find_free_loopdev(const char *path, size_t path_len); +------------------------------------------------------------------------------- + +This function finds a free loopdev and returns the free loopdev minor (-1 for no +free loopdev). If path is non-NULL, it will be filled with free loopdev path. +We can call tst_find_free_loopdev(NULL, 0) in tests to get a free minor number +without changing lib internal state. + +[source,c] +------------------------------------------------------------------------------- +#include "tst_test.h" + unsigned long tst_dev_bytes_written(const char *dev); ------------------------------------------------------------------------------- diff --git a/include/tst_device.h b/include/tst_device.h index 61902b7e0..42b9fa95b 100644 --- a/include/tst_device.h +++ b/include/tst_device.h @@ -44,6 +44,11 @@ int tst_umount(const char *path); */ int tst_clear_device(const char *dev); +/* + * Finds a free loop device for use and returns the free loopdev minor(-1 for no + * free loopdev). If path is non-NULL, it will be filled with free loopdev path. + */ +int tst_find_free_loopdev(const char *path, size_t path_len); /* * Reads test block device stat file and returns the bytes written since the * last call of this function. diff --git a/lib/tst_device.c b/lib/tst_device.c index 65fcc1337..f2516fb08 100644 --- a/lib/tst_device.c +++ b/lib/tst_device.c @@ -53,22 +53,22 @@ static const char *dev_variants[] = { "/dev/block/loop%i" }; -static int set_dev_path(int dev) +static int set_dev_path(int dev, char *path, size_t path_len) { unsigned int i; struct stat st; for (i = 0; i < ARRAY_SIZE(dev_variants); i++) { - snprintf(dev_path, sizeof(dev_path), dev_variants[i], dev); + snprintf(path, path_len, dev_variants[i], dev); - if (stat(dev_path, &st) == 0 && S_ISBLK(st.st_mode)) + if (stat(path, &st) == 0 && S_ISBLK(st.st_mode)) return 1; } return 0; } -static int find_free_loopdev(void) +int tst_find_free_loopdev(char *path, size_t path_len) { int ctl_fd, dev_fd, rc, i; struct loop_info loopinfo; @@ -80,12 +80,14 @@ static int find_free_loopdev(void) rc = ioctl(ctl_fd, LOOP_CTL_GET_FREE); close(ctl_fd); if (rc >= 0) { - set_dev_path(rc); - tst_resm(TINFO, "Found free device '%s'", dev_path); - return 0; + if (path) + set_dev_path(rc, path, path_len); + tst_resm(TINFO, "Found free device %d '%s'", + rc, path ?: ""); + return rc; } tst_resm(TINFO, "Couldn't find free loop device"); - return 1; + return -1; } switch (errno) { @@ -104,24 +106,24 @@ static int find_free_loopdev(void) * Older way is to iterate over /dev/loop%i and /dev/loop/%i and try * LOOP_GET_STATUS ioctl() which fails for free loop devices. */ - for (i = 0; i < 256; i++) { + for (i = 0; path && i < 256; i++) { - if (!set_dev_path(i)) + if (!set_dev_path(i, path, path_len)) continue; - dev_fd = open(dev_path, O_RDONLY); + dev_fd = open(path, O_RDONLY); if (dev_fd < 0) continue; if (ioctl(dev_fd, LOOP_GET_STATUS, &loopinfo) == 0) { - tst_resm(TINFO, "Device '%s' in use", dev_path); + tst_resm(TINFO, "Device '%s' in use", path); } else { if (errno != ENXIO) continue; - tst_resm(TINFO, "Found free device '%s'", dev_path); + tst_resm(TINFO, "Found free device '%s'", path); close(dev_fd); - return 0; + return i; } close(dev_fd); @@ -129,7 +131,7 @@ static int find_free_loopdev(void) tst_resm(TINFO, "No free devices found"); - return 1; + return -1; } static int attach_device(const char *dev, const char *file) @@ -274,7 +276,7 @@ const char *tst_acquire_device__(unsigned int size) return NULL; } - if (find_free_loopdev()) + if (tst_find_free_loopdev(dev_path, sizeof(dev_path)) == -1) return NULL; if (attach_device(dev_path, DEV_FILE)) From patchwork Wed Jul 17 09:44:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Xu X-Patchwork-Id: 1133218 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=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=none (p=none dis=none) header.from=cn.fujitsu.com Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45pXSL6ZlTz9sBF for ; Wed, 17 Jul 2019 19:45:22 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 485E03C1D45 for ; Wed, 17 Jul 2019 11:45:20 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-3.smtp.seeweb.it (in-3.smtp.seeweb.it [IPv6:2001:4b78:1:20::3]) by picard.linux.it (Postfix) with ESMTP id 9DD953C1CA0 for ; Wed, 17 Jul 2019 11:45:12 +0200 (CEST) Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by in-3.smtp.seeweb.it (Postfix) with ESMTP id 8DB321A00EF8 for ; Wed, 17 Jul 2019 11:45:11 +0200 (CEST) X-IronPort-AV: E=Sophos;i="5.64,273,1559491200"; d="scan'208";a="71629117" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 17 Jul 2019 17:45:10 +0800 Received: from G08CNEXCHPEKD02.g08.fujitsu.local (unknown [10.167.33.83]) by cn.fujitsu.com (Postfix) with ESMTP id 9DC054CDE65E; Wed, 17 Jul 2019 17:45:09 +0800 (CST) Received: from localhost.localdomain (10.167.215.46) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 17 Jul 2019 17:45:14 +0800 From: Yang Xu To: Date: Wed, 17 Jul 2019 17:44:35 +0800 Message-ID: <1563356676-2384-2-git-send-email-xuyang2018.jy@cn.fujitsu.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1563356676-2384-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> References: <20190711125108.GB8709@rei> <1563356676-2384-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.215.46] X-yoursite-MailScanner-ID: 9DC054CDE65E.AF622 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: xuyang2018.jy@cn.fujitsu.com X-Spam-Status: No, score=0.0 required=7.0 tests=SPF_HELO_NONE,SPF_NONE autolearn=disabled version=3.4.0 X-Virus-Scanned: clamav-milter 0.99.2 at in-3.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-3.smtp.seeweb.it Subject: [LTP] [PATCH v5 2/3] syscalls/copy_file_range01: add cross-device test X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ltp@lists.linux.it Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" Amir has relaxed cross-device constraint since kernel commit 5dae222a5(vfs: allow copy_file_range to copy across devices), I think we can test it in copy_file_range01. Signed-off-by: Yang Xu Reviewed-by: Amir Goldstein --- .../copy_file_range/copy_file_range01.c | 58 ++++++++++++++----- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c index a5bd5e7f7..ec55e5da1 100644 --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c @@ -24,7 +24,16 @@ static int page_size; static int errcount, numcopies; -static int fd_in, fd_out; +static int fd_in, fd_out, cross_sup; + +static struct tcase { + char *path; + int flags; + char *message; +} tcases[] = { + {FILE_DEST_PATH, 0, "non cross-device"}, + {FILE_MNTED_PATH, 1, "cross-device"}, +}; static int check_file_content(const char *fname1, const char *fname2, loff_t *off1, loff_t *off2, size_t len) @@ -90,7 +99,7 @@ static int check_file_offset(const char *m, int fd, loff_t len, return ret; } -static void test_one(size_t len, loff_t *off_in, loff_t *off_out) +static void test_one(size_t len, loff_t *off_in, loff_t *off_out, char *path) { int ret; size_t to_copy = len; @@ -131,7 +140,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out) to_copy -= TST_RET; } while (to_copy > 0); - ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH, + ret = check_file_content(FILE_SRC_PATH, path, off_in, off_out, len); if (ret) { tst_res(TFAIL, "file contents do not match"); @@ -149,10 +158,10 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out) } } -static void open_files(void) +static void open_files(char *path) { fd_in = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY); - fd_out = SAFE_OPEN(FILE_DEST_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0644); + fd_out = SAFE_OPEN(path, O_CREAT | O_WRONLY | O_TRUNC, 0644); } static void close_files(void) @@ -163,9 +172,16 @@ static void close_files(void) SAFE_CLOSE(fd_in); } -static void copy_file_range_verify(void) +static void copy_file_range_verify(unsigned int n) { int i, j, k; + struct tcase *tc = &tcases[n]; + + if (tc->flags && !cross_sup) { + tst_res(TCONF, + "copy_file_range doesn't support cross-device, skip it"); + return; + } errcount = numcopies = 0; size_t len_arr[] = {11, page_size-1, page_size, page_size+1}; @@ -182,33 +198,41 @@ static void copy_file_range_verify(void) for (i = 0; i < (int)ARRAY_SIZE(len_arr); i++) for (j = 0; j < num_offsets; j++) for (k = 0; k < num_offsets; k++) { - open_files(); - test_one(len_arr[i], off_arr[j], off_arr[k]); + open_files(tc->path); + test_one(len_arr[i], off_arr[j], off_arr[k], tc->path); close_files(); numcopies++; } if (errcount == 0) tst_res(TPASS, - "copy_file_range completed all %d copy jobs successfully!", - numcopies); + "%s copy_file_range completed all %d copy jobs successfully!", + tc->message, numcopies); else - tst_res(TFAIL, "copy_file_range failed %d of %d copy jobs.", - errcount, numcopies); + tst_res(TFAIL, "%s copy_file_range failed %d of %d copy jobs.", + tc->message, errcount, numcopies); } static void setup(void) { - int i, fd; + int i, fd, fd_test; syscall_info(); page_size = getpagesize(); - + cross_sup = 1; fd = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664); /* Writing page_size * 4 of data into test file */ for (i = 0; i < (int)(page_size * 4); i++) SAFE_WRITE(1, fd, CONTENT, CONTSIZE); + + fd_test = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664); + TEST(sys_copy_file_range(fd, 0, fd_test, 0, CONTSIZE, 0)); + if (TST_ERR == EXDEV) + cross_sup = 0; + + SAFE_CLOSE(fd_test); + remove(FILE_MNTED_PATH); SAFE_CLOSE(fd); } @@ -220,7 +244,11 @@ static void cleanup(void) static struct tst_test test = { .setup = setup, .cleanup = cleanup, + .tcnt = ARRAY_SIZE(tcases), .needs_tmpdir = 1, - .test_all = copy_file_range_verify, + .mount_device = 1, + .mntpoint = MNTPOINT, + .all_filesystems = 1, + .test = copy_file_range_verify, .test_variants = TEST_VARIANTS, }; From patchwork Wed Jul 17 09:44:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Xu X-Patchwork-Id: 1133219 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=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=none (p=none dis=none) header.from=cn.fujitsu.com Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45pXSV2lfNz9sBF for ; Wed, 17 Jul 2019 19:45:30 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 89DBB3C1D4A for ; Wed, 17 Jul 2019 11:45:27 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-3.smtp.seeweb.it (in-3.smtp.seeweb.it [IPv6:2001:4b78:1:20::3]) by picard.linux.it (Postfix) with ESMTP id 5F0AA3C1D15 for ; Wed, 17 Jul 2019 11:45:19 +0200 (CEST) Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by in-3.smtp.seeweb.it (Postfix) with ESMTP id 67B5D1A01203 for ; Wed, 17 Jul 2019 11:45:17 +0200 (CEST) X-IronPort-AV: E=Sophos;i="5.64,273,1559491200"; d="scan'208";a="71629145" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 17 Jul 2019 17:45:16 +0800 Received: from G08CNEXCHPEKD02.g08.fujitsu.local (unknown [10.167.33.83]) by cn.fujitsu.com (Postfix) with ESMTP id 1EB354CDE8D8; Wed, 17 Jul 2019 17:45:15 +0800 (CST) Received: from localhost.localdomain (10.167.215.46) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 17 Jul 2019 17:45:19 +0800 From: Yang Xu To: Date: Wed, 17 Jul 2019 17:44:36 +0800 Message-ID: <1563356676-2384-3-git-send-email-xuyang2018.jy@cn.fujitsu.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1563356676-2384-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> References: <20190711125108.GB8709@rei> <1563356676-2384-1-git-send-email-xuyang2018.jy@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.215.46] X-yoursite-MailScanner-ID: 1EB354CDE8D8.A0AE3 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: xuyang2018.jy@cn.fujitsu.com X-Spam-Status: No, score=0.0 required=7.0 tests=SPF_HELO_NONE,SPF_NONE autolearn=disabled version=3.4.0 X-Virus-Scanned: clamav-milter 0.99.2 at in-3.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-3.smtp.seeweb.it Subject: [LTP] [PATCH v5 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ltp@lists.linux.it Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" Since Amir patch[1] for copy_file_range has been merged into upstream kernel, we should add swapfile, immutable file, bounds tests in ltp. Also, add block,char,pipe dev tests and remove EXDEV test(the cross-device constraint has been relaxed since[2]). I follow xfstests code[3][4][5]. [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96e6e8f4a [2]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5 [3]https://patchwork.kernel.org/patch/10971759/ [4]https://patchwork.kernel.org/patch/10971747/ [5]https://patchwork.kernel.org/patch/10961421/ Signed-off-by: Yang Xu Reviewed-by: Amir Goldstein --- include/lapi/fs.h | 7 + .../copy_file_range/copy_file_range.h | 14 +- .../copy_file_range/copy_file_range02.c | 146 +++++++++++++++--- 3 files changed, 146 insertions(+), 21 deletions(-) diff --git a/include/lapi/fs.h b/include/lapi/fs.h index 42cb4f9b2..5cfdb5450 100644 --- a/include/lapi/fs.h +++ b/include/lapi/fs.h @@ -35,4 +35,11 @@ #define FS_NODUMP_FL 0x00000040 /* do not dump file */ #endif +/* Referred form linux kernel include/linux/fs.h */ +#if __WORDSIZE == 64 + #define MAX_LFS_FILESIZE ((loff_t)LLONG_MAX) +#else + #define MAX_LFS_FILESIZE ((loff_t)ULONG_MAX << PAGE_SHIFT) +#endif + #endif diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h index b6d132978..aedfda966 100644 --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h @@ -9,7 +9,10 @@ #include #include +#include +#include #include "lapi/syscalls.h" +#include "lapi/fs.h" #define TEST_VARIANTS 2 @@ -18,10 +21,19 @@ #define FILE_DEST_PATH "file_dest" #define FILE_RDONL_PATH "file_rdonl" #define FILE_DIR_PATH "file_dir" -#define FILE_MNTED_PATH MNTPOINT"/file_mnted" +#define FILE_MNTED_PATH MNTPOINT"/file_mnted" +#define FILE_IMMUTABLE_PATH "file_immutable" +#define FILE_SWAP_PATH "file_swap" +#define FILE_BLKDEV "file_blk" +#define FILE_CHRDEV "/dev/null" +#define FILE_FIFO "file_fifo" +#define FILE_COPY_PATH "file_copy" #define CONTENT "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n" #define CONTSIZE (sizeof(CONTENT) - 1) +#define MAX_LEN MAX_LFS_FILESIZE +#define MIN_OFF 65537 +#define MAX_OFF (MAX_LEN - MIN_OFF) static void syscall_info(void) { diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c index 07c0207c2..ee45b7636 100644 --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c @@ -10,15 +10,25 @@ * * 1) Try to copy contents to file open as readonly * -> EBADF - * 2) Try to copy contents to file on different mounted - * filesystem -> EXDEV - * 3) Try to copy contents to directory -> EISDIR - * 4) Try to copy contents to a file opened with the + * 2) Try to copy contents to directory -> EISDIR + * 3) Try to copy contents to a file opened with the * O_APPEND flag -> EBADF - * 5) Try to copy contents to closed filedescriptor + * 4) Try to copy contents to closed filedescriptor * -> EBADF - * 6) Try to copy contents with invalid 'flags' value + * 5) Try to copy contents with invalid 'flags' value * -> EINVAL + * 6) Try to copy contents to a file chattred with +i + * flag -> EPERM + * 7) Try to copy contents to a swapfile ->ETXTBSY + * 8) Try to copy contents to the samefile with overlapping + * ->EINVAL + * 9) Try to copy contents to a blkdev ->EINVAL + * 10) Try to copy contents to a chardev ->EINVAL + * 11) Try to copy contents to a FIFO ->EINVAL + * 12) Try to copy contents to a file with length beyond + * 16EiB wraps around 0 -> EOVERFLOW + * 13) Try to copy contents to a file with target file range + * beyond maximum supported file size ->EFBIG */ #define _GNU_SOURCE @@ -29,30 +39,78 @@ static int fd_src; static int fd_dest; static int fd_rdonly; -static int fd_mnted; static int fd_dir; static int fd_closed; static int fd_append; +static int fd_immutable; +static int fd_swapfile; +static int fd_dup; +static int fd_blkdev; +static int fd_chrdev; +static int fd_fifo; +static int fd_copy; + +static int chattr_i_nsup; +static int swap_nsup; +static int loop_devn; static struct tcase { int *copy_to_fd; int flags; int exp_err; + loff_t dst; + loff_t len; } tcases[] = { - {&fd_rdonly, 0, EBADF}, - {&fd_mnted, 0, EXDEV}, - {&fd_dir, 0, EISDIR}, - {&fd_append, 0, EBADF}, - {&fd_closed, 0, EBADF}, - {&fd_dest, -1, EINVAL}, + {&fd_rdonly, 0, EBADF, 0, CONTSIZE}, + {&fd_dir, 0, EISDIR, 0, CONTSIZE}, + {&fd_append, 0, EBADF, 0, CONTSIZE}, + {&fd_closed, 0, EBADF, 0, CONTSIZE}, + {&fd_dest, -1, EINVAL, 0, CONTSIZE}, + {&fd_immutable, 0, EPERM, 0, CONTSIZE}, + {&fd_swapfile, 0, ETXTBSY, 0, CONTSIZE}, + {&fd_dup, 0, EINVAL, 0, CONTSIZE/2}, + {&fd_blkdev, 0, EINVAL, 0, CONTSIZE}, + {&fd_chrdev, 0, EINVAL, 0, CONTSIZE}, + {&fd_fifo, 0, EINVAL, 0, CONTSIZE}, + {&fd_copy, 0, EOVERFLOW, MAX_OFF, ULLONG_MAX}, + {&fd_copy, 0, EFBIG, MAX_OFF, MIN_OFF}, }; +static int run_command(char *command, char *option, char *file) +{ + const char *const cmd[] = {command, option, file, NULL}; + int ret; + + ret = tst_run_cmd(cmd, NULL, NULL, 1); + switch (ret) { + case 0: + return 0; + case 255: + tst_res(TCONF, "%s binary not installed", command); + return 1; + default: + tst_res(TCONF, "%s exited with %i", command, ret); + return 2; + } +} + static void verify_copy_file_range(unsigned int n) { struct tcase *tc = &tcases[n]; - + if (tc->copy_to_fd == &fd_immutable && chattr_i_nsup) { + tst_res(TCONF, "filesystem doesn't support chattr +i, skip it"); + return; + } + if (tc->copy_to_fd == &fd_swapfile && swap_nsup) { + tst_res(TCONF, "filesystem doesn't support swapfile, skip it"); + return; + } + if (tc->copy_to_fd == &fd_blkdev && loop_devn == -1) { + tst_res(TCONF, "filesystem doesn't have free loopdev, skip it"); + return; + } TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd, - 0, CONTSIZE, tc->flags)); + &tc->dst, tc->len, tc->flags)); if (TST_RET == -1) { if (tc->exp_err == TST_ERR) { @@ -76,14 +134,27 @@ static void cleanup(void) SAFE_CLOSE(fd_append); if (fd_dir > 0) SAFE_CLOSE(fd_dir); - if (fd_mnted > 0) - SAFE_CLOSE(fd_mnted); if (fd_rdonly > 0) SAFE_CLOSE(fd_rdonly); if (fd_dest > 0) SAFE_CLOSE(fd_dest); if (fd_src > 0) SAFE_CLOSE(fd_src); + if (fd_immutable > 0) { + run_command("chattr", "-i", FILE_IMMUTABLE_PATH); + SAFE_CLOSE(fd_immutable); + } + if (fd_swapfile > 0) { + run_command("swapoff", FILE_SWAP_PATH, NULL); + SAFE_CLOSE(fd_swapfile); + } + if (fd_dup > 0) + SAFE_CLOSE(fd_dup); + if (loop_devn >= 0) + SAFE_UNLINK(FILE_BLKDEV); + if (fd_copy > 0) + SAFE_CLOSE(fd_copy); + SAFE_UNLINK(FILE_FIFO); } static void setup(void) @@ -92,17 +163,52 @@ static void setup(void) if (access(FILE_DIR_PATH, F_OK) == -1) SAFE_MKDIR(FILE_DIR_PATH, 0777); + /* + * tst_find_free_loopdev() returns the free loopdev minor, we make a + * non-instantiated loop device by using it, avoid overwriting its + * content on used loopdev. + */ + loop_devn = tst_find_free_loopdev(NULL, 0); + if (loop_devn >= 0) + SAFE_MKNOD(FILE_BLKDEV, S_IFBLK | 0777, makedev(7, loop_devn)); + + SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0); fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664); fd_dest = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664); fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664); - fd_mnted = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664); fd_dir = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY); fd_closed = -1; fd_append = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT | O_APPEND, 0664); + fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664); + fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600); + fd_blkdev = SAFE_OPEN(FILE_BLKDEV, O_RDWR, 0600); + fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600); + fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600); + + SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE); + close(fd_src); + fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664); + fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666); + + fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664); + chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH); + + if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) { + tst_res(TCONF, "Insufficient disk space to create swap file"); + swap_nsup = 3; + return; + } + + if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) { + tst_res(TCONF, "Failed to create swapfile"); + swap_nsup = 4; + return; + } - SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE); + swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL); + swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL); } static struct tst_test test = { @@ -113,6 +219,6 @@ static struct tst_test test = { .needs_root = 1, .mount_device = 1, .mntpoint = MNTPOINT, - .dev_fs_type = "ext4", + .all_filesystems = 1, .test_variants = TEST_VARIANTS, };