Linux Test Project
 help / color / mirror / Atom feed
From: Gaurav Pathak <gpathak@suse.de>
To: ltp@lists.linux.it
Cc: Gaurav Pathak <gaurav.pathak@suse.com>
Subject: [LTP] [PATCH] syscalls/statx13: Add basic test for STATX_WRITE_ATOMIC on regular file
Date: Thu, 17 Sep 2026 08:26:57 +0530	[thread overview]
Message-ID: <20260917025657.327887-1-gpathak@suse.de> (raw)

From: Gaurav Pathak <gaurav.pathak@suse.com>

This patch adds a new test to validate these atomic write limit fields.
The test ensures the filesystem correctly advertises the STATX_ATTR_WRITE_ATOMIC
attribute when queried on a file opened with O_DIRECT. It also verifies that the
reported optimized maximum is logically consistent by falling within the
absolute minimum and maximum boundaries. Furthermore, it checks that all
reported atomic write unit sizes are valid powers of two, adhering to the strict
requirements of the kernel block layer.

If the underlying storage hardware or filesystem lacks atomic write
support, the test gracefully skips with TCONF.

Fixes: #1224

Signed-off-by: Gaurav Pathak <gaurav.pathak@suse.com>
---
 configure.ac                               |   2 +-
 testcases/kernel/syscalls/statx/.gitignore |   1 +
 testcases/kernel/syscalls/statx/statx13.c  | 130 +++++++++++++++++++++
 3 files changed, 132 insertions(+), 1 deletion(-)
 create mode 100644 testcases/kernel/syscalls/statx/statx13.c

diff --git a/configure.ac b/configure.ac
index 18bfdb88c..72f423c56 100644
--- a/configure.ac
+++ b/configure.ac
@@ -181,7 +181,7 @@ AC_CHECK_MEMBERS([struct iocb.aio_rw_flags],,,[#include <linux/aio_abi.h>])
 AC_CHECK_MEMBERS([struct fanotify_event_info_fid.fsid.__val],,,[#include <sys/fanotify.h>])
 AC_CHECK_MEMBERS([struct perf_event_mmap_page.aux_head],,,[#include <linux/perf_event.h>])
 AC_CHECK_MEMBERS([struct sigaction.sa_sigaction],[],[],[#include <signal.h>])
-AC_CHECK_MEMBERS([struct statx.stx_mnt_id, struct statx.stx_dio_mem_align],,,[
+AC_CHECK_MEMBERS([struct statx.stx_mnt_id, struct statx.stx_dio_mem_align, struct statx.stx_atomic_write_unit_max_opt],,,[
 #define _GNU_SOURCE
 #include <sys/stat.h>
 ])
diff --git a/testcases/kernel/syscalls/statx/.gitignore b/testcases/kernel/syscalls/statx/.gitignore
index f6a423eed..e601a46a3 100644
--- a/testcases/kernel/syscalls/statx/.gitignore
+++ b/testcases/kernel/syscalls/statx/.gitignore
@@ -10,3 +10,4 @@
 /statx10
 /statx11
 /statx12
+/statx13
diff --git a/testcases/kernel/syscalls/statx/statx13.c b/testcases/kernel/syscalls/statx/statx13.c
new file mode 100644
index 000000000..5f73807b4
--- /dev/null
+++ b/testcases/kernel/syscalls/statx/statx13.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 SUSE LLC <gaurav.pathak@suse.com>
+ */
+
+/*\
+ * This test validates the STATX_WRITE_ATOMIC feature (introduced in Linux 6.13).
+ * It ensures that supported filesystems (xfs as of now) correctly report their
+ * atomic write limits to user space when queried via statx().
+ *
+ * The test performs the following validations:
+ * - Creates a test file using O_DIRECT (a prerequisite for atomic writes).
+ * - Calls statx() with the STATX_WRITE_ATOMIC mask to retrieve the limits.
+ * - Verifies that stx_atomic_write_unit_min, stx_atomic_write_unit_max, and
+ *    stx_atomic_write_unit_max_opt are logically consistent (e.g., max_opt is
+ *    within the min and max bounds).
+ * - Ensures all reported atomic write unit sizes are valid powers of two.
+ */
+
+#define _GNU_SOURCE
+#include <sys/param.h>
+#include "tst_test.h"
+
+#define MNTPOINT "mnt_point"
+#define TESTFILE MNTPOINT"/testfile"
+#define MODE 0644
+
+#define WRITE_SIZE 4096
+#define ALIGNMENT  4096
+
+static int file_fd = -1;
+
+static void verify_statx(void)
+{
+	struct statx buff;
+
+	TST_EXP_PASS_SILENT(statx(AT_FDCWD, TESTFILE, 0, STATX_BASIC_STATS | STATX_WRITE_ATOMIC, &buff),
+			"statx(AT_FDCWD, %s, 0, STATX_WRITE_ATOMIC, &buf)", TESTFILE);
+
+	if (!(buff.stx_attributes & STATX_ATTR_WRITE_ATOMIC)) {
+		tst_res(TCONF, "Filesystem does not support STATX_WRITE_ATOMIC");
+		return;
+	}
+
+	if (buff.stx_atomic_write_unit_min > 0 &&
+			__builtin_popcount(buff.stx_atomic_write_unit_min) == 1)
+		tst_res(TPASS, "stx_atomic_write_unit_min(%u) is power of 2",
+				buff.stx_atomic_write_unit_min);
+	else
+		tst_res(TFAIL, "stx_atomic_write_unit_min(%u) is not a power of 2",
+				buff.stx_atomic_write_unit_min);
+
+	if (buff.stx_atomic_write_unit_max > 0 &&
+			__builtin_popcount(buff.stx_atomic_write_unit_max) == 1)
+		tst_res(TPASS, "stx_atomic_write_unit_max(%u) is power of 2",
+				buff.stx_atomic_write_unit_max);
+	else
+		tst_res(TFAIL, "stx_atomic_write_unit_max(%u) is not a power of 2",
+				buff.stx_atomic_write_unit_max);
+
+#ifdef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT
+	if (buff.stx_atomic_write_unit_max_opt == 0) {
+		tst_res(TINFO, "stx_atomic_write_unit_max_opt is 0 (no optimized max reported)");
+	} else {
+		if (buff.stx_atomic_write_unit_max_opt > buff.stx_atomic_write_unit_max)
+			tst_res(TFAIL, "stx_atomic_write_unit_max_opt (%u) exceeds max (%u)",
+					buff.stx_atomic_write_unit_max_opt,
+					buff.stx_atomic_write_unit_max);
+
+		else if (buff.stx_atomic_write_unit_max_opt < buff.stx_atomic_write_unit_min)
+			tst_res(TFAIL, "stx_atomic_write_unit_max_opt (%u) is less than min (%u)",
+					buff.stx_atomic_write_unit_max_opt,
+					buff.stx_atomic_write_unit_min);
+		else
+			tst_res(TPASS, "stx_atomic_write_unit_max_opt (%u) is within valid range [%u, %u]",
+					buff.stx_atomic_write_unit_max_opt,
+					buff.stx_atomic_write_unit_min,
+					buff.stx_atomic_write_unit_max);
+
+		if (__builtin_popcount(buff.stx_atomic_write_unit_max_opt) != 1)
+			tst_res(TFAIL, "stx_atomic_write_unit_max_opt (%u) is not a power of 2",
+					buff.stx_atomic_write_unit_max_opt);
+	}
+#else
+    tst_res(TCONF, "stx_atomic_write_unit_max_opt is not defined in struct statx");
+#endif
+}
+
+static void setup(void)
+{
+	char *data_buff = SAFE_MEMALIGN(ALIGNMENT, WRITE_SIZE);
+
+	if (strcmp(tst_device->fs_type, "xfs") && strcmp(tst_device->fs_type, "ext4"))
+		tst_brk(TCONF, "This test only supports ext4 and xfs");
+
+	umask(0);
+	memset(data_buff, '@', WRITE_SIZE);
+
+	file_fd =  SAFE_OPEN(TESTFILE, O_RDWR | O_CREAT | O_DIRECT, MODE);
+	SAFE_WRITE(SAFE_WRITE_ALL, file_fd, data_buff, WRITE_SIZE);
+}
+
+static void cleanup(void)
+{
+	if (file_fd > -1)
+		SAFE_CLOSE(file_fd);
+}
+
+static struct tst_test test = {
+	.test_all = verify_statx,
+	.setup = setup,
+	.cleanup = cleanup,
+	.min_kver = "6.13",
+	.needs_root = 1,
+	.needs_device = 1,
+	.needs_tmpdir = 1,
+	.mntpoint = MNTPOINT,
+	.mount_device = 1,
+	.filesystems = (struct tst_fs[]) {
+		{
+			.type = "xfs",
+			.mkfs_opts = (const char *const []){"-f", "-bsize=16K", NULL},
+		},
+        {
+            .type = "ext4",
+            .mkfs_opts = (const char *const []){"-O", "bigalloc", "-b", "4096", "-C", "65536", NULL},
+        },
+		{}
+	},
+};
-- 
2.51.0


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

             reply	other threads:[~2026-09-17  6:45 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-17  2:56 Gaurav Pathak [this message]
2026-09-17 10:53 ` [LTP] [PATCH] syscalls/statx13: Add basic test for STATX_WRITE_ATOMIC on regular file Gaurav Pathak
2026-09-17 11:17   ` [LTP] " linuxtestproject.agent
2026-09-17 14:19   ` [LTP] [PATCH] " Petr Vorel
2026-09-18 11:04     ` gpathak
2026-09-17 14:23   ` Petr Vorel
2026-09-18 11:12     ` [LTP] [PATCH v3] " Gaurav Pathak
2026-09-18 12:51       ` [LTP] " linuxtestproject.agent
2026-10-05 13:18         ` Andrea Cervesato via ltp
2026-10-08 14:26   ` [LTP] [PATCH] " Andrea Cervesato via ltp
2026-09-17 11:15 ` [LTP] " linuxtestproject.agent

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=20260917025657.327887-1-gpathak@suse.de \
    --to=gpathak@suse.de \
    --cc=gaurav.pathak@suse.com \
    --cc=ltp@lists.linux.it \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox