1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2022 SUSE LLC <mdoucha@suse.cz>
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 and xfs support statx syscall since the following commit
21 *
22 * commit 93bc420ed41df63a18ae794101f7cbf45226a6ef
23 * Author: yangerkun <yangerkun@huawei.com>
24 * Date: Mon Feb 18 09:07:02 2019 +0800
25 *
26 * ext2: support statx syscall
27 *
28 * commit 99652ea56a4186bc5bf8a3721c5353f41b35ebcb
29 * Author: David Howells <dhowells@redhat.com>
30 * Date: Fri Mar 31 18:31:56 2017 +0100
31 *
32 * ext4: Add statx support
33 *
34 * commit 04a87e3472828f769a93655d7c64a27573bdbc2c
35 * Author: Yonghong Song <yhs@fb.com>
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 <darrick.wong@oracle.com>
42 * Date: Fri Mar 31 18:32:03 2017 +0100
43 *
44 * xfs: report crtime and attribute flags to statx
45 */
46
47 #define _GNU_SOURCE
48 #include "tst_test.h"
49 #include "lapi/fs.h"
50 #include <stdlib.h>
51 #include "lapi/stat.h"
52
53 #define MOUNT_POINT "mntpoint"
54 #define TESTDIR MOUNT_POINT "/testdir"
55
56 #define ATTR(x) {.attr = x, .name = #x}
57
58 static struct {
59 uint64_t attr;
60 const char *name;
61 } attr_list[] = {
62 ATTR(STATX_ATTR_COMPRESSED),
63 ATTR(STATX_ATTR_APPEND),
64 ATTR(STATX_ATTR_IMMUTABLE),
65 ATTR(STATX_ATTR_NODUMP)
66 };
67
68 static uint64_t expected_mask;
69
setup(void)70 static void setup(void)
71 {
72 size_t i;
73 int fd;
74
75 SAFE_MKDIR(TESTDIR, 0777);
76
77 /* Check general inode attribute support */
78 fd = SAFE_OPEN(TESTDIR, O_RDONLY | O_DIRECTORY);
79 TEST(ioctl(fd, FS_IOC_GETFLAGS, &i));
80 SAFE_CLOSE(fd);
81
82 if (TST_RET == -1 && TST_ERR == ENOTTY)
83 tst_brk(TCONF | TTERRNO, "Inode attributes not supported");
84
85 if (TST_RET)
86 tst_brk(TBROK | TTERRNO, "Unexpected ioctl() error");
87
88 for (i = 0, expected_mask = 0; i < ARRAY_SIZE(attr_list); i++)
89 expected_mask |= attr_list[i].attr;
90
91 /* STATX_ATTR_COMPRESSED not supported on XFS */
92 if (!strcmp(tst_device->fs_type, "xfs"))
93 expected_mask &= ~STATX_ATTR_COMPRESSED;
94
95 /* Attribute support was added to Btrfs statx() in kernel v4.13 */
96 if (!strcmp(tst_device->fs_type, "btrfs") && tst_kvercmp(4, 13, 0) < 0)
97 tst_brk(TCONF, "statx() attributes not supported on Btrfs");
98 }
99
run(void)100 static void run(void)
101 {
102 size_t i;
103 struct statx buf;
104
105 TST_EXP_PASS_SILENT(statx(AT_FDCWD, TESTDIR, 0, 0, &buf));
106
107 for (i = 0; i < ARRAY_SIZE(attr_list); i++) {
108 if (!(expected_mask & attr_list[i].attr))
109 continue;
110
111 if (buf.stx_attributes_mask & attr_list[i].attr)
112 tst_res(TPASS, "%s is supported", attr_list[i].name);
113 else
114 tst_res(TFAIL, "%s not supported", attr_list[i].name);
115 }
116 }
117
118 static struct tst_test test = {
119 .test_all = run,
120 .setup = setup,
121 .needs_root = 1,
122 .all_filesystems = 1,
123 .mount_device = 1,
124 .mntpoint = MOUNT_POINT,
125 .min_kver = "4.11",
126 .skip_filesystems = (const char *const[]) {
127 "fuse",
128 NULL
129 },
130 .tags = (const struct tst_tag[]) {
131 {"linux-git", "93bc420ed41d"},
132 {"linux-git", "99652ea56a41"},
133 {"linux-git", "04a87e347282"},
134 {"linux-git", "5f955f26f3d4"},
135 {}
136 },
137 };
138