diff mbox series

[v2,3/7] Add ioctl_ficlone02 test

Message ID 20240723-ioctl_ficlone-v2-3-33075bbc117f@suse.com
State Accepted
Headers show
Series Add ioctl_ficlone testing suite | expand

Commit Message

Andrea Cervesato July 23, 2024, 7:15 a.m. UTC
From: Andrea Cervesato <andrea.cervesato@suse.com>

This test verifies that ioctl() FICLONE/FICLONERANGE feature
correctly raises EOPNOTSUPP when unsupported filesystem is used.
In particular, filesystems which don't support copy-on-write.

Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 runtest/syscalls                                  |  1 +
 testcases/kernel/syscalls/ioctl/.gitignore        |  1 +
 testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c | 70 +++++++++++++++++++++++
 3 files changed, 72 insertions(+)

Comments

Petr Vorel July 29, 2024, 11:53 a.m. UTC | #1
Hi all,

> This test verifies that ioctl() FICLONE/FICLONERANGE feature
> correctly raises EOPNOTSUPP when unsupported filesystem is used.
> In particular, filesystems which don't support copy-on-write.

This test, merged as [1] fails on bcachefs:

$ cd testcases/kernel/syscalls/ioctl/
# # LTP_SINGLE_FS_TYPE=bcachefs ./ioctl_ficlone02
tst_buffers.c:57: TINFO: Test is using guarded buffers
tst_tmpdir.c:316: TINFO: Using /tmp/LTP_iocu1xhKp as tmpdir (tmpfs filesystem)
tst_device.c:96: TINFO: Found free device 0 '/dev/loop0'
tst_test.c:1806: TINFO: LTP version: 20240524-131-gdfb293ee0
tst_test.c:1650: TINFO: Timeout per run is 0h 00m 30s
tst_supported_fs_types.c:161: TINFO: WARNING: testing only bcachefs
tst_supported_fs_types.c:97: TINFO: Kernel supports bcachefs
tst_supported_fs_types.c:62: TINFO: mkfs.bcachefs does exist
tst_test.c:1746: TINFO: === Testing on bcachefs ===
tst_test.c:1111: TINFO: Formatting /dev/loop0 with bcachefs opts='' extra opts=''
tst_test.c:1123: TINFO: Mounting /dev/loop0 to /tmp/LTP_iocu1xhKp/mnt fstyp=bcachefs flags=0
ioctl_ficlone02.c:33: TFAIL: ioctl(dst_fd, FICLONE, src_fd) succeeded
ioctl_ficlone02.c:34: TFAIL: ioctl(dst_fd, FICLONERANGE, clone_range) expected EOPNOTSUPP: EINVAL (22)

I tested only kernel 6.10 and 6.9, fails on both. Maybe it's just a different
errno set...

Kind regards,
Petr

[1] https://github.com/linux-test-project/ltp/commit/d70bfb185c9aa52aeab9b9893055eec7fc969a4f
Cyril Hrubis July 29, 2024, 12:03 p.m. UTC | #2
Hi!
> This test, merged as [1] fails on bcachefs:
> 
> $ cd testcases/kernel/syscalls/ioctl/
> # # LTP_SINGLE_FS_TYPE=bcachefs ./ioctl_ficlone02
> tst_buffers.c:57: TINFO: Test is using guarded buffers
> tst_tmpdir.c:316: TINFO: Using /tmp/LTP_iocu1xhKp as tmpdir (tmpfs filesystem)
> tst_device.c:96: TINFO: Found free device 0 '/dev/loop0'
> tst_test.c:1806: TINFO: LTP version: 20240524-131-gdfb293ee0
> tst_test.c:1650: TINFO: Timeout per run is 0h 00m 30s
> tst_supported_fs_types.c:161: TINFO: WARNING: testing only bcachefs
> tst_supported_fs_types.c:97: TINFO: Kernel supports bcachefs
> tst_supported_fs_types.c:62: TINFO: mkfs.bcachefs does exist
> tst_test.c:1746: TINFO: === Testing on bcachefs ===
> tst_test.c:1111: TINFO: Formatting /dev/loop0 with bcachefs opts='' extra opts=''
> tst_test.c:1123: TINFO: Mounting /dev/loop0 to /tmp/LTP_iocu1xhKp/mnt fstyp=bcachefs flags=0
> ioctl_ficlone02.c:33: TFAIL: ioctl(dst_fd, FICLONE, src_fd) succeeded
> ioctl_ficlone02.c:34: TFAIL: ioctl(dst_fd, FICLONERANGE, clone_range) expected EOPNOTSUPP: EINVAL (22)

This looks that FIOCLONE is supported on bcachefs and bcachefs should be
skipped in this test as well. And I suppose that we should enable
bcachefs in the rest of the FICLONE tests too.

BTW, the EINVAL in the second subtest is caused by the fact that we
attempt to clone a range that does not exist, this can be fixed by:

diff --git a/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c b/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c
index be3b01c29..17452a1a3 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c
@@ -43,6 +43,8 @@ static void setup(void)

        SAFE_STAT(MNTPOINT, &sb);

+       tst_fill_file(SRCPATH, 0x00, sb.st_blksize, 1);
+
        clone_range->src_offset = 0;
        clone_range->src_length = sb.st_blksize;
        clone_range->dest_offset = 0;
Petr Vorel July 29, 2024, 9:29 p.m. UTC | #3
Hi Cyril, all,

> Hi!
> > This test, merged as [1] fails on bcachefs:

> > $ cd testcases/kernel/syscalls/ioctl/
> > # # LTP_SINGLE_FS_TYPE=bcachefs ./ioctl_ficlone02
> > tst_buffers.c:57: TINFO: Test is using guarded buffers
> > tst_tmpdir.c:316: TINFO: Using /tmp/LTP_iocu1xhKp as tmpdir (tmpfs filesystem)
> > tst_device.c:96: TINFO: Found free device 0 '/dev/loop0'
> > tst_test.c:1806: TINFO: LTP version: 20240524-131-gdfb293ee0
> > tst_test.c:1650: TINFO: Timeout per run is 0h 00m 30s
> > tst_supported_fs_types.c:161: TINFO: WARNING: testing only bcachefs
> > tst_supported_fs_types.c:97: TINFO: Kernel supports bcachefs
> > tst_supported_fs_types.c:62: TINFO: mkfs.bcachefs does exist
> > tst_test.c:1746: TINFO: === Testing on bcachefs ===
> > tst_test.c:1111: TINFO: Formatting /dev/loop0 with bcachefs opts='' extra opts=''
> > tst_test.c:1123: TINFO: Mounting /dev/loop0 to /tmp/LTP_iocu1xhKp/mnt fstyp=bcachefs flags=0
> > ioctl_ficlone02.c:33: TFAIL: ioctl(dst_fd, FICLONE, src_fd) succeeded
> > ioctl_ficlone02.c:34: TFAIL: ioctl(dst_fd, FICLONERANGE, clone_range) expected EOPNOTSUPP: EINVAL (22)

> This looks that FIOCLONE is supported on bcachefs and bcachefs should be
> skipped in this test as well. And I suppose that we should enable
> bcachefs in the rest of the FICLONE tests too.

Thanks! (I should have read the test description).
I dared to enable it + skip on ioctl_ficlone02.c and merge with your SBT

https://github.com/linux-test-project/ltp/commit/b3d9561793657239548269378d02f65580917e7c

> BTW, the EINVAL in the second subtest is caused by the fact that we
> attempt to clone a range that does not exist, this can be fixed by:

> diff --git a/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c b/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c
> index be3b01c29..17452a1a3 100644
> --- a/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c
> +++ b/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c
> @@ -43,6 +43,8 @@ static void setup(void)

>         SAFE_STAT(MNTPOINT, &sb);

> +       tst_fill_file(SRCPATH, 0x00, sb.st_blksize, 1);
> +
>         clone_range->src_offset = 0;
>         clone_range->src_length = sb.st_blksize;
>         clone_range->dest_offset = 0;

Thanks, again! This is less confusing. I again dared to merge with your SBT:
https://github.com/linux-test-project/ltp/commit/9c6390812831f5c36e531be5a25bd8d7862e79fb

Kind regards,
Petr
diff mbox series

Patch

diff --git a/runtest/syscalls b/runtest/syscalls
index f05386ba2..48fe85c97 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -593,6 +593,7 @@  ioctl_ns07 ioctl_ns07
 ioctl_sg01 ioctl_sg01
 
 ioctl_ficlone01 ioctl_ficlone01
+ioctl_ficlone02 ioctl_ficlone02
 
 inotify_init1_01 inotify_init1_01
 inotify_init1_02 inotify_init1_02
diff --git a/testcases/kernel/syscalls/ioctl/.gitignore b/testcases/kernel/syscalls/ioctl/.gitignore
index 5404aa93f..3d25fdfb2 100644
--- a/testcases/kernel/syscalls/ioctl/.gitignore
+++ b/testcases/kernel/syscalls/ioctl/.gitignore
@@ -23,3 +23,4 @@ 
 /ioctl_ns07
 /ioctl_sg01
 /ioctl_ficlone01
+/ioctl_ficlone02
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c b/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c
new file mode 100644
index 000000000..f6d492026
--- /dev/null
+++ b/testcases/kernel/syscalls/ioctl/ioctl_ficlone02.c
@@ -0,0 +1,70 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 Andrea Cervesato andrea.cervesato@suse.com
+ */
+
+/*\
+ * [Description]
+ *
+ * This test verifies that ioctl() FICLONE/FICLONERANGE feature correctly raises
+ * EOPNOTSUPP when an unsupported filesystem is used. In particular, filesystems
+ * which don't support copy-on-write.
+ */
+
+#include "tst_test.h"
+#include "lapi/fs.h"
+
+#define MNTPOINT "mnt"
+#define SRCPATH MNTPOINT "/file0"
+#define DSTPATH MNTPOINT "/file1"
+
+static struct file_clone_range *clone_range;
+
+static void run(void)
+{
+	int src_fd;
+	int dst_fd;
+
+	src_fd = SAFE_OPEN(SRCPATH, O_CREAT | O_RDWR, 0640);
+	dst_fd = SAFE_OPEN(DSTPATH, O_CREAT | O_RDWR, 0640);
+
+	clone_range->src_fd = src_fd;
+
+	TST_EXP_FAIL(ioctl(dst_fd, FICLONE, src_fd), EOPNOTSUPP);
+	TST_EXP_FAIL(ioctl(dst_fd, FICLONERANGE, clone_range), EOPNOTSUPP);
+
+	SAFE_CLOSE(src_fd);
+	SAFE_CLOSE(dst_fd);
+}
+
+static void setup(void)
+{
+	struct stat sb;
+
+	SAFE_STAT(MNTPOINT, &sb);
+
+	clone_range->src_offset = 0;
+	clone_range->src_length = sb.st_blksize;
+	clone_range->dest_offset = 0;
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.min_kver = "4.5",
+	.needs_root = 1,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1,
+	.skip_filesystems = (const char *[]) {
+		"btrfs",
+		"overlayfs",
+		"nfs",
+		"xfs",
+		NULL,
+	},
+	.bufs = (struct tst_buffers []) {
+		{&clone_range, .size = sizeof(struct file_clone_range)},
+		{},
+	}
+};