xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/statx/statx04.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2022 SUSE LLC <[email protected]>
4  */
5 
6 /*\
7  * [Description]
8  *
9  * Test whether the kernel properly advertises support for statx() attributes:
10  *
11  * - STATX_ATTR_COMPRESSED: The file is compressed by the filesystem.
12  * - STATX_ATTR_IMMUTABLE: The file cannot be modified.
13  * - STATX_ATTR_APPEND: The file can only be opened in append mode for writing.
14  * - STATX_ATTR_NODUMP: File is not a candidate for backup when a backup
15  *                        program such as dump(8) is run.
16  *
17  * xfs filesystem doesn't support STATX_ATTR_COMPRESSED flag, so we only test
18  * three other flags.
19  *
20  * ext2, ext4, btrfs, xfs and tmpfs support statx syscall since the following commit
21  *
22  *  commit 93bc420ed41df63a18ae794101f7cbf45226a6ef
23  *  Author: yangerkun <[email protected]>
24  *  Date:   Mon Feb 18 09:07:02 2019 +0800
25  *
26  *  ext2: support statx syscall
27  *
28  *  commit 99652ea56a4186bc5bf8a3721c5353f41b35ebcb
29  *  Author: David Howells <[email protected]>
30  *  Date:   Fri Mar 31 18:31:56 2017 +0100
31  *
32  *  ext4: Add statx support
33  *
34  *  commit 04a87e3472828f769a93655d7c64a27573bdbc2c
35  *  Author: Yonghong Song <[email protected]>
36  *  Date:   Fri May 12 15:07:43 2017 -0700
37  *
38  *  Btrfs: add statx support
39  *
40  *  commit 5f955f26f3d42d04aba65590a32eb70eedb7f37d
41  *  Author: Darrick J. Wong <[email protected]>
42  *  Date:   Fri Mar 31 18:32:03 2017 +0100
43  *
44  *  xfs: report crtime and attribute flags to statx
45  *
46  *  commit e408e695f5f1f60d784913afc45ff2c387a5aeb8
47  *  Author: Theodore Ts'o <[email protected]>
48  *  Date:   Thu Jul 14 21:59:12 2022 -0400
49  *
50  *  mm/shmem: support FS_IOC_[SG]ETFLAGS in tmpfs
51  *
52  */
53 
54 #define _GNU_SOURCE
55 #include <stdlib.h>
56 #include "tst_test.h"
57 #include "lapi/fs.h"
58 #include "lapi/stat.h"
59 #include "lapi/fcntl.h"
60 
61 #define MOUNT_POINT "mntpoint"
62 #define TESTDIR MOUNT_POINT "/testdir"
63 
64 #define ATTR(x) {.attr = x, .name = #x}
65 
66 static struct {
67 	uint64_t attr;
68 	const char *name;
69 } attr_list[] = {
70 	ATTR(STATX_ATTR_COMPRESSED),
71 	ATTR(STATX_ATTR_APPEND),
72 	ATTR(STATX_ATTR_IMMUTABLE),
73 	ATTR(STATX_ATTR_NODUMP)
74 };
75 
76 static uint64_t expected_mask;
77 
setup(void)78 static void setup(void)
79 {
80 	size_t i;
81 	int fd;
82 
83 	SAFE_MKDIR(TESTDIR, 0777);
84 
85 	/* Check general inode attribute support */
86 	fd = SAFE_OPEN(TESTDIR, O_RDONLY | O_DIRECTORY);
87 	TEST(ioctl(fd, FS_IOC_GETFLAGS, &i));
88 	SAFE_CLOSE(fd);
89 
90 	if (TST_RET == -1 && TST_ERR == ENOTTY)
91 		tst_brk(TCONF | TTERRNO, "Inode attributes not supported");
92 
93 	if (TST_RET)
94 		tst_brk(TBROK | TTERRNO, "Unexpected ioctl() error");
95 
96 	for (i = 0, expected_mask = 0; i < ARRAY_SIZE(attr_list); i++)
97 		expected_mask |= attr_list[i].attr;
98 
99 	/* STATX_ATTR_COMPRESSED not supported on Bcachefs, TMPFS, XFS */
100 	if (!strcmp(tst_device->fs_type, "bcachefs") || !strcmp(tst_device->fs_type, "tmpfs") ||
101 	    !strcmp(tst_device->fs_type, "xfs"))
102 		expected_mask &= ~STATX_ATTR_COMPRESSED;
103 
104 	/* Attribute support was added to Btrfs statx() in kernel v4.13 */
105 	if (!strcmp(tst_device->fs_type, "btrfs") && tst_kvercmp(4, 13, 0) < 0)
106 		tst_brk(TCONF, "statx() attributes not supported on Btrfs");
107 }
108 
run(void)109 static void run(void)
110 {
111 	size_t i;
112 	struct statx buf;
113 
114 	TST_EXP_PASS_SILENT(statx(AT_FDCWD, TESTDIR, 0, 0, &buf));
115 
116 	for (i = 0; i < ARRAY_SIZE(attr_list); i++) {
117 		if (!(expected_mask & attr_list[i].attr))
118 			continue;
119 
120 		if (buf.stx_attributes_mask & attr_list[i].attr)
121 			tst_res(TPASS, "%s is supported", attr_list[i].name);
122 		else
123 			tst_res(TFAIL, "%s not supported", attr_list[i].name);
124 	}
125 }
126 
127 static struct tst_test test = {
128 	.test_all = run,
129 	.setup = setup,
130 	.needs_root = 1,
131 	.all_filesystems = 1,
132 	.mount_device = 1,
133 	.mntpoint = MOUNT_POINT,
134 	.min_kver = "4.11",
135 	.skip_filesystems = (const char *const[]) {
136 		"fuse",
137 		"ntfs",
138 		NULL
139 	},
140 	.tags = (const struct tst_tag[]) {
141 		{"linux-git", "93bc420ed41d"},
142 		{"linux-git", "99652ea56a41"},
143 		{"linux-git", "04a87e347282"},
144 		{"linux-git", "5f955f26f3d4"},
145 		{"linux-git", "e408e695f5f1"},
146 		{}
147 	},
148 };
149