[LTP] [PATCH v2] ioctl_fiemap01: New test for fiemap ioctl()

Wei Gao via ltp
2024-01-18T07:32:56Z

Fixes: #535

Signed-off-by: Wei Gao <wegao@suse.com>
---
runtest/syscalls | 2 +
testcases/kernel/syscalls/ioctl/.gitignore | 1 +
.../kernel/syscalls/ioctl/ioctl_fiemap01.c | 116 ++++++++++++++++++
3 files changed, 119 insertions(+)
create mode 100644 testcases/kernel/syscalls/ioctl/ioctl_fiemap01.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 6e2407879..4e6ce5aef 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -589,6 +589,8 @@ ioctl_ns07 ioctl_ns07

ioctl_sg01 ioctl_sg01

+ioctl_fiemap01 ioctl_fiemap01
+
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 5fff7a61d..64adcdfe6 100644
--- a/testcases/kernel/syscalls/ioctl/.gitignore
+++ b/testcases/kernel/syscalls/ioctl/.gitignore
@@ -22,3 +22,4 @@
/ioctl_ns06
/ioctl_ns07
/ioctl_sg01
+/ioctl_fiemap01
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_fiemap01.c b/testcases/kernel/syscalls/ioctl/ioctl_fiemap01.c
new file mode 100644
index 000000000..a626bb03c
--- /dev/null
+++ b/testcases/kernel/syscalls/ioctl/ioctl_fiemap01.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023 Wei Gao <wegao@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify basic fiemap ioctl
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/fiemap.h>
+#include <stdlib.h>
+
+#include "tst_test.h"
+
+#define TESTFILE "testfile"
+#define NUM_EXTENT 2
+#define FILE_OFFSET ((rand() % 8 + 2) * getpagesize())
+
+static char *buf;
+
+static void print_extens(struct fiemap *fiemap)
+{
+
+ tst_res(TDEBUG, "File extent count: %u", fiemap->fm_mapped_extents);
+ for (unsigned int i = 0; i < fiemap->fm_mapped_extents; ++i) {
+ tst_res(TDEBUG, "Extent %u: Logical offset: %llu, Physical offset: %llu, flags: %u, Length: %llu",
+ i + 1,
+ fiemap->fm_extents[i].fe_logical,
+ fiemap->fm_extents[i].fe_physical,
+ fiemap->fm_extents[i].fe_flags,
+ fiemap->fm_extents[i].fe_length);
+ }
+}
+
+static void verify_ioctl(void)
+{
+ int fd;
+ struct fiemap *fiemap;
+
+ fd = SAFE_OPEN(TESTFILE, O_RDWR | O_CREAT, 0644);
+
+ fiemap = SAFE_MALLOC(sizeof(struct fiemap) + sizeof(struct fiemap_extent) * NUM_EXTENT);
+ fiemap->fm_start = 0;
+ fiemap->fm_length = ~0ULL;
+ fiemap->fm_extent_count = 1;
+
+ fiemap->fm_flags = -1;
+ TST_EXP_FAIL(ioctl(fd, FS_IOC_FIEMAP, fiemap), EBADR);
+
+ fiemap->fm_flags = 0;
+ SAFE_IOCTL(fd, FS_IOC_FIEMAP, fiemap);
+ print_extens(fiemap);
+ if (fiemap->fm_mapped_extents == 0)
+ tst_res(TPASS, "Check fiemap iotct zero fm_mapped_extents pass");
+ else
+ tst_res(TFAIL, "Check fiemap iotct zero fm_mapped_extents failed");
+
+ SAFE_WRITE(SAFE_WRITE_ANY, fd, buf, getpagesize());
+ SAFE_IOCTL(fd, FS_IOC_FIEMAP, fiemap);
+ print_extens(fiemap);
+ if ((fiemap->fm_mapped_extents == 1) && (fiemap->fm_extents[0].fe_physical == 0))
+ tst_res(TPASS, "Check fiemap iotct one fm_mapped_extents pass");
+ else
+ tst_res(TFAIL, "Check fiemap iotct one fm_mapped_extents failed");
+
+ fiemap->fm_flags = FIEMAP_FLAG_SYNC;
+ SAFE_IOCTL(fd, FS_IOC_FIEMAP, fiemap);
+ print_extens(fiemap);
+ if ((fiemap->fm_mapped_extents == 1) &&
+ (fiemap->fm_extents[0].fe_flags == FIEMAP_EXTENT_LAST) &&
+ (fiemap->fm_extents[0].fe_physical > 0) &&
+ (fiemap->fm_extents[0].fe_length == (__u64)getpagesize()))
+ tst_res(TPASS, "Check fiemap iotct FIEMAP_FLAG_SYNC fm_flags pass");
+ else
+ tst_res(TFAIL, "Check fiemap iotct FIEMAP_FLAG_SYNC fm_flags failed");
+
+ fiemap->fm_extent_count = NUM_EXTENT;
+ srand(time(NULL));
+ SAFE_LSEEK(fd, FILE_OFFSET, SEEK_SET);
+ SAFE_WRITE(SAFE_WRITE_ALL, fd, buf, getpagesize());
+ SAFE_IOCTL(fd, FS_IOC_FIEMAP, fiemap);
+ print_extens(fiemap);
+ if ((fiemap->fm_mapped_extents == NUM_EXTENT) &&
+ (fiemap->fm_extents[NUM_EXTENT - 1].fe_flags == FIEMAP_EXTENT_LAST) &&
+ (fiemap->fm_extents[NUM_EXTENT - 1].fe_physical > 0) &&
+ (fiemap->fm_extents[NUM_EXTENT - 1].fe_length == (__u64)getpagesize()))
+ tst_res(TPASS, "Check fiemap iotct multiple fm_mapped_extents pass");
+ else
+ tst_res(TFAIL, "Check fiemap iotct multiple fm_mapped_extents failed");
+
+ free(fiemap);
+ SAFE_CLOSE(fd);
+ unlink(TESTFILE);
+}
+
+static void setup(void)
+{
+ buf = SAFE_MALLOC(getpagesize());
+}
+
+static void cleanup(void)
+{
+ free(buf);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_ioctl,
+ .needs_root = 1,
+ .needs_tmpdir = 1,
+};
--
2.35.3