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