1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
4 * Author: Yang Xu <[email protected]>
5 */
6
7 /*\
8 * [Description]
9 *
10 * It is a basic test for STATX_DIOALIGN mask on ext4 and xfs filesystem.
11 *
12 * - STATX_DIOALIGN Want stx_dio_mem_align and stx_dio_offset_align value
13 *
14 * Check these two values are nonzero under dio situation when STATX_DIOALIGN
15 * in the request mask.
16 *
17 * On ext4, files that use certain filesystem features (data journaling,
18 * encryption, and verity) fall back to buffered I/O. But ltp creates own
19 * filesystem by enabling mount_device in tst_test struct. If we set block
20 * device to LTP_DEV environment, we use this block device to mount by using
21 * default mount option. Otherwise, use loop device to simuate it. So it can
22 * avoid these above situations and don't fall back to buffered I/O.
23 *
24 * Minimum Linux version required is v6.1.
25 */
26
27 #define _GNU_SOURCE
28 #include <sys/types.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <stdbool.h>
32 #include "tst_test.h"
33 #include "lapi/stat.h"
34 #include "lapi/fcntl.h"
35
36 #define MNTPOINT "mnt_point"
37 #define TESTFILE MNTPOINT"/testfile"
38
verify_statx(void)39 static void verify_statx(void)
40 {
41 struct statx buf;
42
43 TST_EXP_PASS_SILENT(statx(AT_FDCWD, TESTFILE, 0, STATX_DIOALIGN, &buf),
44 "statx(AT_FDCWD, %s, 0, STATX_DIOALIGN, &buf)", TESTFILE);
45
46 if (!(buf.stx_mask & STATX_DIOALIGN)) {
47 tst_res(TCONF, "Filesystem does not support STATX_DIOALIGN");
48 return;
49 }
50
51 #ifdef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN
52 if (buf.stx_dio_mem_align != 0)
53 tst_res(TPASS, "stx_dio_mem_align:%u", buf.stx_dio_mem_align);
54 else
55 tst_res(TFAIL, "stx_dio_mem_align was 0, but DIO should be supported");
56
57 if (buf.stx_dio_offset_align != 0)
58 tst_res(TPASS, "stx_dio_offset_align:%u", buf.stx_dio_offset_align);
59 else
60 tst_res(TFAIL, "stx_dio_offset_align was 0, but DIO should be supported");
61 #else
62 tst_res(TCONF, "glibc statx struct miss stx_dio_mem_align field");
63 #endif
64 }
65
setup(void)66 static void setup(void)
67 {
68 int fd = -1;
69
70 if (strcmp(tst_device->fs_type, "xfs") && strcmp(tst_device->fs_type, "ext4"))
71 tst_brk(TCONF, "This test only supports ext4 and xfs");
72
73 SAFE_FILE_PRINTF(TESTFILE, "AAAA");
74 fd = open(TESTFILE, O_RDWR | O_DIRECT);
75 if (fd == -1) {
76 if (errno == EINVAL)
77 tst_brk(TCONF,
78 "The regular file is not on a filesystem that support DIO");
79 else
80 tst_brk(TBROK | TERRNO,
81 "The regular file is open with O_RDWR | O_DIRECT failed");
82 }
83 SAFE_CLOSE(fd);
84 }
85
86 static struct tst_test test = {
87 .test_all = verify_statx,
88 .setup = setup,
89 .needs_root = 1,
90 .mntpoint = MNTPOINT,
91 .mount_device = 1,
92 .all_filesystems = 1,
93 };
94