[LTP] syscalls/statx13: Add basic test for STATX_WRITE_ATOMIC on regular file
linuxtestproject.agent@gmail.com
linuxtestproject.agent@gmail.com
Thu Sep 17 13:17:51 CEST 2026
Hi Gaurav,
On Thu, 17 Sep 2026 16:23:04 +0530, Gaurav Pathak wrote:
> syscalls/statx13: Add basic test for STATX_WRITE_ATOMIC on regular file
> Fixes: #1224
Fixes tags must reference a valid commit SHA in git history. Use
Closes: #1224 or a Link tag to reference an issue.
> -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>
> ])
Do not use configure.ac checks to conditionally compile test logic.
Instead, add fallback definitions for STATX_WRITE_ATOMIC,
STATX_ATTR_WRITE_ATOMIC, and stx_atomic_write_* members in
include/lapi/stat.h so the test builds unconditionally.
> /*\
> * 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).
Add a blank line before the bulleted list to comply with reST syntax.
> #define _GNU_SOURCE
> #include <sys/param.h>
> #include "tst_test.h"
Include "lapi/stat.h" so statx() and atomic write definitions are
available on older C libraries. <sys/param.h> is unused and should be
removed.
> 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_EXP_PASS_SILENT() does not abort on error. If statx() fails, execution
proceeds to read uninitialized memory from buff. Add "if (!TST_PASS)
return;" after the call. Also drop the redundant, mismatched format string.
> 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);
Assert that buff.stx_atomic_write_unit_min <=
buff.stx_atomic_write_unit_max. The ordering between min and max is never
checked when stx_atomic_write_unit_max_opt is 0.
> #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
Do not bury #ifdef feature checks inside test functions. Defining the
members in include/lapi/stat.h removes the need for this guard and TCONF
branch.
> 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);
> }
data_buff is allocated with SAFE_MEMALIGN() but never freed. Free
data_buff after SAFE_WRITE(), and move the allocation after the
filesystem check so it is not leaked on tst_brk(). Also remove the extra
space after the '=' assignment.
> static void cleanup(void)
> {
> if (file_fd > -1)
> SAFE_CLOSE(file_fd);
> }
Use if (file_fd != -1) per LTP conventions.
Also, add an entry for statx13 to runtest/syscalls.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
More information about the ltp
mailing list