1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2023 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 * It is a basic test for STATX_ATTR_MOUNT_ROOT flag.
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * This flag indicates whether the path or fd refers to the root of a mount
13f08c3bdfSopenharmony_ci * or not.
14f08c3bdfSopenharmony_ci *
15f08c3bdfSopenharmony_ci * Minimum Linux version required is v5.8.
16f08c3bdfSopenharmony_ci */
17f08c3bdfSopenharmony_ci
18f08c3bdfSopenharmony_ci#define _GNU_SOURCE
19f08c3bdfSopenharmony_ci#include <unistd.h>
20f08c3bdfSopenharmony_ci#include <stdlib.h>
21f08c3bdfSopenharmony_ci#include <stdbool.h>
22f08c3bdfSopenharmony_ci#include <stdio.h>
23f08c3bdfSopenharmony_ci#include "tst_test.h"
24f08c3bdfSopenharmony_ci#include "lapi/stat.h"
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_ci#define MNTPOINT "mntpoint"
27f08c3bdfSopenharmony_ci#define TESTFILE MNTPOINT"/testfile"
28f08c3bdfSopenharmony_ci
29f08c3bdfSopenharmony_cistatic int dir_fd = -1, file_fd = -1;
30f08c3bdfSopenharmony_ci
31f08c3bdfSopenharmony_cistatic struct tcase {
32f08c3bdfSopenharmony_ci	const char *path;
33f08c3bdfSopenharmony_ci	bool mnt_root;
34f08c3bdfSopenharmony_ci	int *fd;
35f08c3bdfSopenharmony_ci} tcases[] = {
36f08c3bdfSopenharmony_ci	{MNTPOINT, 1, &dir_fd},
37f08c3bdfSopenharmony_ci	{TESTFILE, 0, &file_fd}
38f08c3bdfSopenharmony_ci};
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_cistatic void verify_statx(unsigned int n)
41f08c3bdfSopenharmony_ci{
42f08c3bdfSopenharmony_ci	struct tcase *tc = &tcases[n/2];
43f08c3bdfSopenharmony_ci	struct statx buf;
44f08c3bdfSopenharmony_ci	bool flag = n % 2;
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci	if (flag) {
47f08c3bdfSopenharmony_ci		tst_res(TINFO, "Testing %s with STATX_ATTR_MOUNT_ROOT by fd",
48f08c3bdfSopenharmony_ci				tc->path);
49f08c3bdfSopenharmony_ci		TST_EXP_PASS_SILENT(statx(*tc->fd, "", AT_EMPTY_PATH, 0, &buf));
50f08c3bdfSopenharmony_ci	} else {
51f08c3bdfSopenharmony_ci		tst_res(TINFO, "Testing %s with STATX_ATTR_MOUNT_ROOT by path",
52f08c3bdfSopenharmony_ci				tc->path);
53f08c3bdfSopenharmony_ci		TST_EXP_PASS_SILENT(statx(AT_FDCWD, tc->path, 0, 0, &buf));
54f08c3bdfSopenharmony_ci	}
55f08c3bdfSopenharmony_ci
56f08c3bdfSopenharmony_ci	if (!(buf.stx_attributes_mask & STATX_ATTR_MOUNT_ROOT)) {
57f08c3bdfSopenharmony_ci		tst_res(TCONF, "Filesystem does not support STATX_ATTR_MOUNT_ROOT");
58f08c3bdfSopenharmony_ci		return;
59f08c3bdfSopenharmony_ci	}
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_ci	if (buf.stx_attributes & STATX_ATTR_MOUNT_ROOT) {
62f08c3bdfSopenharmony_ci		tst_res(tc->mnt_root ? TPASS : TFAIL,
63f08c3bdfSopenharmony_ci			"STATX_ATTR_MOUNT_ROOT flag is set");
64f08c3bdfSopenharmony_ci	} else {
65f08c3bdfSopenharmony_ci		tst_res(tc->mnt_root ? TFAIL : TPASS,
66f08c3bdfSopenharmony_ci			"STATX_ATTR_MOUNT_ROOT flag is not set");
67f08c3bdfSopenharmony_ci	}
68f08c3bdfSopenharmony_ci}
69f08c3bdfSopenharmony_ci
70f08c3bdfSopenharmony_cistatic void setup(void)
71f08c3bdfSopenharmony_ci{
72f08c3bdfSopenharmony_ci	SAFE_CREAT(TESTFILE, 0755);
73f08c3bdfSopenharmony_ci	dir_fd = SAFE_OPEN(MNTPOINT, O_DIRECTORY);
74f08c3bdfSopenharmony_ci	file_fd = SAFE_OPEN(TESTFILE, O_RDWR);
75f08c3bdfSopenharmony_ci}
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_cistatic void cleanup(void)
78f08c3bdfSopenharmony_ci{
79f08c3bdfSopenharmony_ci	if (dir_fd > -1)
80f08c3bdfSopenharmony_ci		SAFE_CLOSE(dir_fd);
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci	if (file_fd > -1)
83f08c3bdfSopenharmony_ci		SAFE_CLOSE(file_fd);
84f08c3bdfSopenharmony_ci}
85f08c3bdfSopenharmony_ci
86f08c3bdfSopenharmony_cistatic struct tst_test test = {
87f08c3bdfSopenharmony_ci	.test = verify_statx,
88f08c3bdfSopenharmony_ci	.setup = setup,
89f08c3bdfSopenharmony_ci	.cleanup = cleanup,
90f08c3bdfSopenharmony_ci	.mntpoint = MNTPOINT,
91f08c3bdfSopenharmony_ci	.mount_device = 1,
92f08c3bdfSopenharmony_ci	.all_filesystems = 1,
93f08c3bdfSopenharmony_ci	.needs_root = 1,
94f08c3bdfSopenharmony_ci	.tcnt = 2 * ARRAY_SIZE(tcases)
95f08c3bdfSopenharmony_ci};
96