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