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