• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) Zilogic Systems Pvt. Ltd., 2018
4  * Email: code@zilogic.com
5  */
6 
7 /*
8  * Test statx
9  *
10  * This code tests if the attributes field of statx received expected value.
11  * File set with following flags by using SAFE_IOCTL:
12  * 1) STATX_ATTR_COMPRESSED - The file is compressed by the filesystem.
13  * 2) STATX_ATTR_IMMUTABLE - The file cannot be modified.
14  * 3) STATX_ATTR_APPEND - The file can only be opened in append mode for
15  *                        writing.
16  * 4) STATX_ATTR_NODUMP - File is not a candidate for backup when a backup
17  *                        program such as dump(8) is run.
18  *
19  * Two directories are tested.
20  * First directory has all flags set.
21  * Second directory has no flags set.
22  *
23  * Minimum kernel version required is 4.11.
24  */
25 
26 #define _GNU_SOURCE
27 #include "tst_test.h"
28 #include "lapi/fs.h"
29 #include <stdlib.h>
30 #include "lapi/stat.h"
31 
32 #define MOUNT_POINT "mntpoint"
33 #define TESTDIR_FLAGGED MOUNT_POINT"/test_dir1"
34 #define TESTDIR_UNFLAGGED MOUNT_POINT"/test_dir2"
35 
36 static int fd, clear_flags;
37 
test_flagged(void)38 static void test_flagged(void)
39 {
40 	struct statx buf;
41 
42 	TEST(statx(AT_FDCWD, TESTDIR_FLAGGED, 0, 0, &buf));
43 	if (TST_RET == 0)
44 		tst_res(TPASS,
45 			"sys_statx(AT_FDCWD, %s, 0, 0, &buf)", TESTDIR_FLAGGED);
46 	else
47 		tst_brk(TFAIL | TTERRNO,
48 			"sys_statx(AT_FDCWD, %s, 0, 0, &buf)", TESTDIR_FLAGGED);
49 
50 	if (buf.stx_attributes & STATX_ATTR_COMPRESSED)
51 		tst_res(TPASS, "STATX_ATTR_COMPRESSED flag is set");
52 	else
53 		tst_res(TFAIL, "STATX_ATTR_COMPRESSED flag is not set");
54 
55 	if (buf.stx_attributes & STATX_ATTR_APPEND)
56 		tst_res(TPASS, "STATX_ATTR_APPEND flag is set");
57 	else
58 		tst_res(TFAIL, "STATX_ATTR_APPEND flag is not set");
59 
60 	if (buf.stx_attributes & STATX_ATTR_IMMUTABLE)
61 		tst_res(TPASS, "STATX_ATTR_IMMUTABLE flag is set");
62 	else
63 		tst_res(TFAIL, "STATX_ATTR_IMMUTABLE flag is not set");
64 
65 	if (buf.stx_attributes & STATX_ATTR_NODUMP)
66 		tst_res(TPASS, "STATX_ATTR_NODUMP flag is set");
67 	else
68 		tst_res(TFAIL, "STATX_ATTR_NODUMP flag is not set");
69 }
70 
test_unflagged(void)71 static void test_unflagged(void)
72 {
73 	struct statx buf;
74 
75 	TEST(statx(AT_FDCWD, TESTDIR_UNFLAGGED, 0, 0, &buf));
76 	if (TST_RET == 0)
77 		tst_res(TPASS,
78 			"sys_statx(AT_FDCWD, %s, 0, 0, &buf)",
79 			TESTDIR_UNFLAGGED);
80 	else
81 		tst_brk(TFAIL | TTERRNO,
82 			"sys_statx(AT_FDCWD, %s, 0, 0, &buf)",
83 			TESTDIR_UNFLAGGED);
84 
85 	if ((buf.stx_attributes & STATX_ATTR_COMPRESSED) == 0)
86 		tst_res(TPASS, "STATX_ATTR_COMPRESSED flag is not set");
87 	else
88 		tst_res(TFAIL, "STATX_ATTR_COMPRESSED flag is set");
89 
90 	if ((buf.stx_attributes & STATX_ATTR_APPEND) == 0)
91 		tst_res(TPASS, "STATX_ATTR_APPEND flag is not set");
92 	else
93 		tst_res(TFAIL, "STATX_ATTR_APPEND flag is set");
94 
95 	if ((buf.stx_attributes & STATX_ATTR_IMMUTABLE) == 0)
96 		tst_res(TPASS, "STATX_ATTR_IMMUTABLE flag is not set");
97 	else
98 		tst_res(TFAIL, "STATX_ATTR_IMMUTABLE flag is set");
99 
100 	if ((buf.stx_attributes & STATX_ATTR_NODUMP) == 0)
101 		tst_res(TPASS, "STATX_ATTR_NODUMP flag is not set");
102 	else
103 		tst_res(TFAIL, "STATX_ATTR_NODUMP flag is set");
104 }
105 
106 struct test_cases {
107 	void (*tfunc)(void);
108 } tcases[] = {
109 	{&test_flagged},
110 	{&test_unflagged},
111 };
112 
run(unsigned int i)113 static void run(unsigned int i)
114 {
115 	tcases[i].tfunc();
116 }
117 
caid_flags_setup(void)118 static void caid_flags_setup(void)
119 {
120 	int attr, ret;
121 
122 	fd = SAFE_OPEN(TESTDIR_FLAGGED, O_RDONLY | O_DIRECTORY);
123 
124 	ret = ioctl(fd, FS_IOC_GETFLAGS, &attr);
125 	if (ret < 0) {
126 		if (errno == ENOTTY)
127 			tst_brk(TCONF | TERRNO, "FS_IOC_GETFLAGS not supported");
128 
129 		/* ntfs3g fuse fs returns wrong errno for unimplemented ioctls */
130 		if (!strcmp(tst_device->fs_type, "ntfs")) {
131 			tst_brk(TCONF | TERRNO,
132 				"ntfs3g does not support FS_IOC_GETFLAGS");
133 		}
134 
135 		tst_brk(TBROK | TERRNO, "ioctl(%i, FS_IOC_GETFLAGS, ...)", fd);
136 	}
137 
138 	attr |= FS_COMPR_FL | FS_APPEND_FL | FS_IMMUTABLE_FL | FS_NODUMP_FL;
139 
140 	ret = ioctl(fd, FS_IOC_SETFLAGS, &attr);
141 	if (ret < 0) {
142 		if (errno == EOPNOTSUPP)
143 			tst_brk(TCONF, "Flags not supported");
144 		tst_brk(TBROK | TERRNO, "ioctl(%i, FS_IOC_SETFLAGS, %i)", fd, attr);
145 	}
146 
147 	clear_flags = 1;
148 }
149 
setup(void)150 static void setup(void)
151 {
152 	SAFE_MKDIR(TESTDIR_FLAGGED, 0777);
153 	SAFE_MKDIR(TESTDIR_UNFLAGGED, 0777);
154 
155 	if (!strcmp(tst_device->fs_type, "btrfs") && tst_kvercmp(4, 13, 0) < 0)
156 		tst_brk(TCONF, "Btrfs statx() supported since 4.13");
157 
158 	caid_flags_setup();
159 }
160 
cleanup(void)161 static void cleanup(void)
162 {
163 	int attr;
164 
165 	if (clear_flags) {
166 		SAFE_IOCTL(fd, FS_IOC_GETFLAGS, &attr);
167 		attr &= ~(FS_COMPR_FL | FS_APPEND_FL | FS_IMMUTABLE_FL | FS_NODUMP_FL);
168 		SAFE_IOCTL(fd, FS_IOC_SETFLAGS, &attr);
169 	}
170 
171 	if (fd > 0)
172 		SAFE_CLOSE(fd);
173 }
174 
175 static struct tst_test test = {
176 	.test = run,
177 	.tcnt = ARRAY_SIZE(tcases),
178 	.setup = setup,
179 	.cleanup = cleanup,
180 	.needs_root = 1,
181 	.all_filesystems = 1,
182 	.mount_device = 1,
183 	.mntpoint = MOUNT_POINT,
184 	.min_kver = "4.11",
185 };
186