[PATCH v4 3/9] lib: Add support for max_kver to struct tst_test and tst_fs

Petr Vorel <[email protected]> Wed, 5 Aug 2026 17:14:45 +0200
Newsgroups gmane.linux.ltp
Message-ID <[email protected]>
max_kver adds a support to require a maximal kernel version the test can
run on. e.g. "7.2" (mainline release) or "6.1.180" (stable release).

NOTE: Mainline release is sufficient on any stable release (test with
.min_kver = "7.1" runs also on kernel 7.1.5). Stable releases are
compared as expected.

Signed-off-by: Petr Vorel <[email protected]>
---
Changes v3->v4:
* Mention flag in doc/developers/writing_tests.rst
* Fix doc (agent):
- * on any stable release (test with ``min_kver = "7.1"`` runs also on kernel
+ * on any stable release (test with ``max_kver = "7.1"`` runs also on kernel
* Fix checkpatch style (agent):
-       for (i=0, dots=0; max_kver[i]; i++)
+       for (i = 0, dots = 0; max_kver[i]; i++)

 doc/developers/writing_tests.rst |  3 +++
 include/tst_test.h               | 13 +++++++++-
 lib/tst_test.c                   | 43 ++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/doc/developers/writing_tests.rst b/doc/developers/writing_tests.rst
index 4db57898fc..376ca1534d 100644
--- a/doc/developers/writing_tests.rst
+++ b/doc/developers/writing_tests.rst
@@ -402,6 +402,9 @@ LTP C And Shell Test API Comparison
     * - .min_kver
       - TST_MIN_KVER
 
+    * - .max_kver
+      - not implemented
+
     * - .min_mem_avail
       - not applicable
 
diff --git a/include/tst_test.h b/include/tst_test.h
index c69362485e..30c32b844e 100644
--- a/include/tst_test.h
+++ b/include/tst_test.h
@@ -280,6 +280,9 @@ struct tst_ulimit_val {
  *
  * @min_kver: A minimum kernel version supporting the filesystem which has been
  *            created with mkfs.
+ *
+ * @max_kver: A maximum kernel version supporting the filesystem which has been
+ *            created with mkfs.
  */
 struct tst_fs {
 	const char *type;
@@ -292,6 +295,7 @@ struct tst_fs {
 	const void *mnt_data;
 
 	const char *min_kver;
+	const char *max_kver;
 };
 
 /**
@@ -301,7 +305,13 @@ struct tst_fs {
  *        and each time passed an increasing counter value.
  * @options: An NULL optstr terminated array of struct tst_option.
  *
- * @min_kver: A minimal kernel version the test can run on. e.g. "3.10".
+ * @min_kver: A minimal kernel version the test can run on. e.g. "4.4" (mainline
+ * release) or "6.1.180" (stable release).
+ *
+ * @max_kver: A maximal kernel version the test can run on. e.g. "7.2" (mainline
+ * release) or "6.1.180" (stable release). NOTE: Mainline release is sufficient
+ * on any stable release (test with ``max_kver = "7.1"`` runs also on kernel
+ * 7.1.5). Stable releases are compared as expected.
  *
  * @supported_archs: A NULL terminated array of architectures the test runs on
  *                   e.g. {"x86_64, "x86", NULL}. Calls tst_is_on_arch() to
@@ -551,6 +561,7 @@ struct tst_fs {
 	struct tst_option *options;
 
 	const char *min_kver;
+	const char *max_kver;
 
 	const char *const *supported_archs;
 
diff --git a/lib/tst_test.c b/lib/tst_test.c
index c42dcf14e4..0d3714c709 100644
--- a/lib/tst_test.c
+++ b/lib/tst_test.c
@@ -1083,6 +1083,40 @@ static bool check_min_kver(const char *min_kver, const int brk_nosupp)
 	return true;
 }
 
+/*
+ * Check for the maximal required kernel version.
+ *
+ * return: true if the kernel version is low enough, false otherwise.
+ */
+static bool check_max_kver(const char *max_kver, const int brk_nosupp)
+{
+	char *msg;
+	int dots, i, v1, v2, v3;
+
+	tst_parse_kver(max_kver, &v1, &v2, &v3);
+
+	for (i = 0, dots = 0; max_kver[i]; i++)
+		dots += (max_kver[i] == '.');
+
+	/*
+	 * For mainline kernel release without patch level (single dot e.g. "7.1")
+	 * ignore v3 (the sublevel): 7.1.x is always ok.
+	 * Do *not* ignore v3 on stable kernel release (2 dots, e.g. 7.1.5).
+	 */
+	if (tst_kvercmp(v1, v2, v3) > (dots == 1 ? 1023 : 0)) {
+		msg = "The test requires kernel %s or older";
+
+		if (brk_nosupp)
+			tst_brk(TCONF, msg, max_kver);
+		else
+			tst_res(TCONF, msg, max_kver);
+
+		return false;
+	}
+
+	return true;
+}
+
 /*
  * Checks if the struct results values are equal.
  *
@@ -1459,6 +1493,9 @@ static void do_setup(int argc, char *argv[])
 	if (tst_test->min_kver)
 		check_min_kver(tst_test->min_kver, 1);
 
+	if (tst_test->max_kver)
+		check_max_kver(tst_test->max_kver, 1);
+
 	if (tst_test->skip_in_lockdown && tst_lockdown_enabled() > 0)
 		tst_brk(TCONF, "Kernel is locked down, skipping test");
 
@@ -1582,6 +1619,9 @@ static void do_setup(int argc, char *argv[])
 			if (tst_test->filesystems && tst_test->filesystems->min_kver)
 				check_min_kver(tst_test->filesystems->min_kver, 1);
 
+			if (tst_test->filesystems && tst_test->filesystems->max_kver)
+				check_max_kver(tst_test->filesystems->max_kver, 1);
+
 			prepare_device(tst_test->filesystems);
 		}
 	}
@@ -1987,6 +2027,9 @@ static void run_tcase_on_fs(struct tst_fs *fs, const char *fs_type)
 	if (fs->min_kver && !check_min_kver(fs->min_kver, 0))
 		return;
 
+	if (fs->max_kver && !check_max_kver(fs->max_kver, 0))
+		return;
+
 	prepare_device(fs);
 
 	fork_testrun();
-- 
2.55.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp