From: Wei Gao via ltp <ltp@lists.linux.it>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH v14] fsconfig04: Check FSCONFIG_SET_PATH
Date: Wed, 9 Sep 2026 03:34:31 +0000 [thread overview]
Message-ID: <20260909033447.14302-1-wegao@suse.com> (raw)
In-Reply-To: <20260813052853.22152-1-wegao@suse.com>
The fsconfig01.c does not test if FSCONFIG_SET_PATH has any effect;
most of the calls there just set a dummy "sync" parameter. This test
case aims to verify if the FSCONFIG_SET_PATH operation can be used
to dynamically change the external journal device of an ext3 or ext4
filesystem.
Closes: https://github.com/linux-test-project/ltp/issues/1169
Signed-off-by: Wei Gao <wegao@suse.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
---
v13->v14:
- Eliminated redundant static 'dev0' buffer and strcpy() by directly using 'tst_device->dev' from the framework.
- Removed global mutable option-formatting buffers and arrays, replacing them with a local stack-based helper function 'format_journal_device()'.
- Replaced manual if-else results reporting with the standard LTP 'TST_EXP_EXPR()' macro.
- Relocated 'SAFE_CLOSE(fd)' to execute immediately after 'FSCONFIG_CMD_CREATE' succeeds to free the kernel filesystem context early.
runtest/syscalls | 1 +
testcases/kernel/syscalls/fsconfig/.gitignore | 1 +
.../kernel/syscalls/fsconfig/fsconfig04.c | 171 ++++++++++++++++++
3 files changed, 173 insertions(+)
create mode 100644 testcases/kernel/syscalls/fsconfig/fsconfig04.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 65fb4d1ce..13bb59cde 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -437,6 +437,7 @@ fremovexattr02 fremovexattr02
fsconfig01 fsconfig01
fsconfig02 fsconfig02
fsconfig03 fsconfig03
+fsconfig04 fsconfig04
fsmount01 fsmount01
fsmount02 fsmount02
diff --git a/testcases/kernel/syscalls/fsconfig/.gitignore b/testcases/kernel/syscalls/fsconfig/.gitignore
index cfedae5f7..bd3754c34 100644
--- a/testcases/kernel/syscalls/fsconfig/.gitignore
+++ b/testcases/kernel/syscalls/fsconfig/.gitignore
@@ -1,3 +1,4 @@
/fsconfig01
/fsconfig02
/fsconfig03
+/fsconfig04
diff --git a/testcases/kernel/syscalls/fsconfig/fsconfig04.c b/testcases/kernel/syscalls/fsconfig/fsconfig04.c
new file mode 100644
index 000000000..842a9dffc
--- /dev/null
+++ b/testcases/kernel/syscalls/fsconfig/fsconfig04.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Wei Gao <wegao@suse.com>
+ */
+
+/*\
+ * This test aims to validate :manpage:`fsconfig(2)` with the
+ * ``FSCONFIG_SET_PATH`` operation in dynamically altering the external
+ * journal device of an ext3 or ext4 filesystem.
+ *
+ * Root privileges are required because the test creates and formats loop
+ * devices, and configures filesystems.
+ *
+ * [Algorithm]
+ *
+ * - Acquire three loop devices (``tst_device->dev`` from framework, ``dev1``, ``dev2``).
+ * - Format ``dev1`` and ``dev2`` as external journal devices with the same UUID
+ * (``-O journal_dev -U <uuid>``).
+ * - Format ``tst_device->dev`` three times to cycle journal associations:
+ * ``dev1`` -> ``dev2`` -> ``dev1``, so both journal superblocks are consistent.
+ * - Open ``tst_device->dev`` via :manpage:`fsopen(2)` and set the source and journal_path using
+ * :manpage:`fsconfig(2)` (``FSCONFIG_SET_STRING``) and
+ * :manpage:`fsconfig(2)` (``FSCONFIG_SET_PATH``).
+ * - Apply ``FSCONFIG_CMD_CREATE`` and verify with ``tune2fs`` that ``tst_device->dev``'s
+ * journal device is now ``dev2``.
+ *
+ * Implementation notes:
+ *
+ * - To avoid ``journal UUID does not match`` error when switching external
+ * journal device, we have to assign the same UUID to ``dev1``/``dev2``.
+ * - Before the :manpage:`fsconfig(2)` test, we have to format ``tst_device->dev`` associating to
+ * ``dev1`` -> ``dev2`` -> ``dev1``. This ensures that both ``dev1``/``dev2`` superblocks contain
+ * correct content. Otherwise, you will encounter errors such as
+ * ``EXT4-fs (loop0): External journal has more than one user (unsupported)``
+ * when switching the external journal device using :manpage:`fsconfig(2)`.
+ */
+
+#include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
+#include "lapi/fsmount.h"
+
+#define MNTPOINT "mntpoint"
+#define LOOP_DEV_SIZE 10
+#define UUID "d73c9e5e-97e4-4a9c-b17e-75a931b02660"
+
+static int fd = -1;
+static char dev1[PATH_MAX];
+static char dev2[PATH_MAX];
+
+static const char *const mkfs_opts_set_UUID[] = {"-F", "-U", UUID, "-O", "journal_dev", NULL};
+
+static void cleanup(void)
+{
+ if (fd != -1)
+ SAFE_CLOSE(fd);
+
+ if (dev1[0])
+ tst_detach_device(dev1);
+
+ if (dev2[0])
+ tst_detach_device(dev2);
+}
+
+static void create_and_attach_loopdev(const char *filename, char *dev_path, size_t dev_path_len)
+{
+ if (tst_prealloc_file(filename, 1024 * 1024, LOOP_DEV_SIZE))
+ tst_brk(TBROK, "Failed to create %s", filename);
+
+ if (tst_find_free_loopdev(dev_path, dev_path_len) == -1)
+ tst_brk(TBROK, "No free loop device found for %s", filename);
+
+ if (tst_attach_device(dev_path, filename))
+ tst_brk(TBROK, "Failed to attach %s to %s", filename, dev_path);
+}
+
+static void format_journal_device(const char *dev, const char *journal)
+{
+ char journal_opt[PATH_MAX + 16];
+ const char *const opts[] = {"-F", "-J", journal_opt, NULL};
+
+ snprintf(journal_opt, sizeof(journal_opt), "device=%s", journal);
+ SAFE_MKFS(dev, tst_device->fs_type, opts, NULL);
+}
+
+static void setup(void)
+{
+ fsopen_supported_by_kernel();
+
+ create_and_attach_loopdev("dev1_file", dev1, sizeof(dev1));
+ create_and_attach_loopdev("dev2_file", dev2, sizeof(dev2));
+}
+
+static void run(void)
+{
+ /* Reset dev1, dev2 and tst_device->dev superblocks before each test run iteration */
+ SAFE_MKFS(dev1, tst_device->fs_type, mkfs_opts_set_UUID, NULL);
+ SAFE_MKFS(dev2, tst_device->fs_type, mkfs_opts_set_UUID, NULL);
+ format_journal_device(tst_device->dev, dev1);
+ format_journal_device(tst_device->dev, dev2);
+ format_journal_device(tst_device->dev, dev1);
+
+ TEST(fd = fsopen(tst_device->fs_type, 0));
+ if (fd == -1)
+ tst_brk(TBROK | TTERRNO, "fsopen() failed");
+
+ TEST(fsconfig(fd, FSCONFIG_SET_STRING, "source", tst_device->dev, 0));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TTERRNO, "fsconfig(FSCONFIG_SET_STRING) failed");
+
+ TEST(fsconfig(fd, FSCONFIG_SET_PATH, "journal_path", dev2, 0));
+ if (TST_RET == -1) {
+ if (TST_ERR == EOPNOTSUPP)
+ tst_brk(TCONF, "fsconfig(FSCONFIG_SET_PATH) not supported");
+ else
+ tst_brk(TFAIL | TTERRNO, "fsconfig(FSCONFIG_SET_PATH) failed");
+ }
+
+ TEST(fsconfig(fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0));
+ if (TST_RET == -1)
+ tst_brk(TFAIL | TTERRNO, "fsconfig(FSCONFIG_CMD_CREATE) failed");
+
+ SAFE_CLOSE(fd);
+
+ char path[PATH_MAX + 32];
+ char device_str[NAME_MAX];
+ bool found = false;
+ struct stat st;
+
+ SAFE_STAT(dev2, &st);
+ unsigned int device_num = (minor(st.st_rdev) & 0xff) | (major(st.st_rdev) << 8) |
+ ((minor(st.st_rdev) & ~0xff) << 12);
+ snprintf(device_str, sizeof(device_str), "0x%04x", device_num);
+
+ char line[PATH_MAX];
+ FILE *tune2fs;
+
+ snprintf(path, sizeof(path), "tune2fs -l %s 2>&1", tst_device->dev);
+ tune2fs = SAFE_POPEN(path, "r");
+
+ while (fgets(line, PATH_MAX, tune2fs)) {
+ if (*line && strstr(line, "Journal device:") && strstr(line, device_str)) {
+ found = true;
+ break;
+ }
+ }
+
+ TST_EXP_EXPR(found, "Device found in journal");
+
+ pclose(tune2fs);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_root = 1,
+ .needs_device = 1,
+ .mntpoint = MNTPOINT,
+ .needs_cmds = (struct tst_cmd []) {
+ {.cmd = "tune2fs"},
+ {}
+ },
+ .filesystems = (struct tst_fs []) {
+ {.type = "ext3"},
+ {.type = "ext4"},
+ {}
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
next prev parent reply other threads:[~2026-09-09 3:35 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-16 15:10 [LTP] [PATCH v1] fsconfig04.c: Check FSCONFIG_SET_PATH Wei Gao via ltp
2025-05-22 20:56 ` Petr Vorel
2025-05-26 14:29 ` Wei Gao via ltp
2025-05-26 6:40 ` Petr Vorel
2025-05-26 14:35 ` [LTP] [PATCH v2] " Wei Gao via ltp
2025-05-26 9:54 ` Petr Vorel
2025-05-26 12:54 ` Cyril Hrubis
2025-05-26 16:13 ` Petr Vorel
2025-05-27 8:24 ` Cyril Hrubis
2025-05-27 8:58 ` [LTP] LTP doc: test examples [was: Re: [PATCH v2] fsconfig04.c: Check FSCONFIG_SET_PATH] Petr Vorel
2025-05-26 14:38 ` [LTP] [PATCH v2] fsconfig04.c: Check FSCONFIG_SET_PATH Cyril Hrubis
2025-06-03 21:45 ` [LTP] [PATCH v3] " Wei Gao via ltp
2025-10-17 4:39 ` Wei Gao via ltp
2025-12-12 9:29 ` Andrea Cervesato via ltp
2026-02-25 9:27 ` Wei Gao via ltp
2026-03-16 8:49 ` Petr Vorel
2026-03-17 0:59 ` Wei Gao via ltp
2026-03-24 12:50 ` Petr Vorel
2026-04-10 5:47 ` [LTP] [PATCH v4] " Wei Gao via ltp
2026-04-16 11:25 ` [LTP] [PATCH v5] fsconfig04: " Wei Gao via ltp
2026-04-16 13:52 ` [LTP] " linuxtestproject.agent
2026-04-16 13:55 ` Andrea Cervesato via ltp
2026-04-30 5:19 ` [LTP] [PATCH v6] " Wei Gao via ltp
2026-04-30 6:34 ` [LTP] " linuxtestproject.agent
2026-05-07 12:25 ` Wei Gao via ltp
2026-06-09 9:44 ` [LTP] [PATCH v6] " Andrea Cervesato via ltp
2026-06-10 5:21 ` [LTP] [PATCH v7] " Wei Gao via ltp
2026-06-10 10:06 ` [LTP] " linuxtestproject.agent
2026-06-18 2:38 ` [LTP] [PATCH v8] " Wei Gao via ltp
2026-06-18 4:04 ` [LTP] " linuxtestproject.agent
2026-06-26 6:14 ` [LTP] [PATCH v9] " Wei Gao via ltp
2026-06-26 9:33 ` [LTP] " linuxtestproject.agent
2026-07-13 12:08 ` [LTP] [PATCH v9] " Andrea Cervesato via ltp
2026-07-20 12:26 ` [LTP] [PATCH v10] " Wei Gao via ltp
2026-07-20 13:11 ` [LTP] " linuxtestproject.agent
2026-08-03 2:12 ` [LTP] [PATCH v11] " Wei Gao via ltp
2026-08-03 3:37 ` [LTP] " linuxtestproject.agent
2026-08-04 1:04 ` [LTP] [PATCH v12] " Wei Gao via ltp
2026-08-04 4:17 ` [LTP] " linuxtestproject.agent
2026-08-05 3:11 ` Wei Gao via ltp
2026-08-11 7:44 ` Andrea Cervesato via ltp
2026-08-06 11:30 ` [LTP] [PATCH v12] " Petr Vorel
2026-08-13 5:28 ` [LTP] [PATCH v13] " Wei Gao via ltp
2026-08-13 6:19 ` [LTP] " linuxtestproject.agent
2026-09-04 12:51 ` [LTP] [PATCH v13] " Andrea Cervesato via ltp
2026-09-09 3:20 ` Wei Gao via ltp
2026-09-09 3:34 ` Wei Gao via ltp [this message]
2026-09-09 8:00 ` [LTP] " linuxtestproject.agent
2026-09-09 10:03 ` [LTP] [PATCH v15] " Wei Gao via ltp
2026-09-09 10:34 ` [LTP] " linuxtestproject.agent
2026-09-16 7:28 ` [LTP] [PATCH v16] " Wei Gao via ltp
2026-09-16 13:28 ` [LTP] " linuxtestproject.agent
2026-09-17 1:41 ` Wei Gao via ltp
2026-09-18 12:06 ` Petr Vorel
2026-09-17 2:45 ` [LTP] [PATCH v16] " Wei Gao via ltp
2026-09-17 2:45 ` Wei Gao via ltp
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260909033447.14302-1-wegao@suse.com \
--to=ltp@lists.linux.it \
--cc=wegao@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.