Skip to content

Commit b2eeaed

Browse files
committed
mount_setattr01: add open_tree_attr variant
This patch simply introduces a new variant to the mount_setattr01 test, in order to verify that open_tree_attr() works correctly. The open_tree_attr() syscall has been introduced in the kernel v6.15 by commit "c4a16820d901 - fs: add open_tree_attr()". Reviewed-by: Petr Vorel <pvorel@suse.cz> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
1 parent 772bdbc commit b2eeaed

File tree

1 file changed

+65
-18
lines changed

1 file changed

+65
-18
lines changed

testcases/kernel/syscalls/mount_setattr/mount_setattr01.c

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
* Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.
44
* Author: Dai Shili <daisl.fnst@fujitsu.com>
55
* Author: Chen Hanxiao <chenhx.fnst@fujitsu.com>
6+
* Copyright (C) 2025 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
67
*/
78

89
/*\
9-
* Basic mount_setattr() test.
10+
* Basic mount_setattr()/open_tree_attr() test.
1011
* Test whether the basic mount attributes are set correctly.
1112
*
1213
* Verify some MOUNT_SETATTR(2) attributes:
@@ -22,14 +23,16 @@
2223
* - MOUNT_ATTR_NODIRATIME - prevents updating access time for
2324
* directories on this mount
2425
*
25-
* The functionality was added in v5.12.
26+
* The mount_setattr functionality was added in v5.12, while the open_tree_attr
27+
* functionality was added in v6.15.
2628
*/
2729

2830
#define _GNU_SOURCE
2931

3032
#include <sys/statvfs.h>
3133
#include "tst_test.h"
3234
#include "lapi/fsmount.h"
35+
#include "lapi/syscalls.h"
3336

3437
#define MNTPOINT "mntpoint"
3538
#define OT_MNTPOINT "ot_mntpoint"
@@ -40,7 +43,23 @@
4043
.expect_attrs = exp_attrs \
4144
}
4245

46+
static int open_tree_variant1(struct mount_attr *attr);
47+
static int open_tree_variant2(struct mount_attr *attr);
48+
4349
static int mount_flag, otfd = -1;
50+
struct mount_attr *attr;
51+
52+
static struct tsetattr_variant {
53+
int (*child_variant)(struct mount_attr *attr);
54+
char *desc;
55+
} tvariants[] = {
56+
#if (__NR_mount_setattr != __LTP__NR_INVALID_SYSCALL)
57+
{ .child_variant = &open_tree_variant1, "mount_setattr()" },
58+
#endif
59+
#if (__NR_open_tree_attr != __LTP__NR_INVALID_SYSCALL)
60+
{ .child_variant = &open_tree_variant2, "open_tree_attr()"},
61+
#endif
62+
};
4463

4564
static struct tcase {
4665
char *name;
@@ -66,39 +85,62 @@ static void cleanup(void)
6685
static void setup(void)
6786
{
6887
fsopen_supported_by_kernel();
69-
struct stat st = {0};
7088

71-
if (stat(OT_MNTPOINT, &st) == -1)
89+
if (access(OT_MNTPOINT, F_OK) != 0)
7290
SAFE_MKDIR(OT_MNTPOINT, 0777);
7391
}
7492

93+
static int open_tree_variant1(struct mount_attr *attr)
94+
{
95+
tst_res(TINFO, "Using variant open_tree() + mount_setattr()");
96+
97+
otfd = TST_EXP_FD_SILENT(open_tree(AT_FDCWD, MNTPOINT,
98+
AT_EMPTY_PATH | OPEN_TREE_CLONE));
99+
if (otfd == -1)
100+
return -1;
101+
102+
TST_EXP_PASS(mount_setattr(otfd, "", AT_EMPTY_PATH,
103+
attr, sizeof(*attr)));
104+
if (TST_RET == -1) {
105+
SAFE_CLOSE(otfd);
106+
return -1;
107+
}
108+
109+
return otfd;
110+
}
111+
112+
static int open_tree_variant2(struct mount_attr *attr)
113+
{
114+
otfd = TST_EXP_FD(open_tree_attr(AT_FDCWD, MNTPOINT,
115+
AT_EMPTY_PATH | OPEN_TREE_CLONE,
116+
attr, sizeof(*attr)));
117+
118+
return otfd;
119+
}
120+
75121
static void run(unsigned int n)
76122
{
77123
struct tcase *tc = &tcases[n];
78-
struct mount_attr attr = {
79-
.attr_set = tc->mount_attrs,
80-
};
124+
struct tsetattr_variant *tv = &tvariants[tst_variant];
81125
struct statvfs buf;
82126

83-
TST_EXP_FD_SILENT(open_tree(AT_FDCWD, MNTPOINT, AT_EMPTY_PATH |
84-
AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE));
85-
if (!TST_PASS)
86-
return;
127+
tst_res(TINFO, "Using variant %s", tv->desc);
87128

88-
otfd = (int)TST_RET;
129+
memset(attr, 0, sizeof(*attr));
130+
attr->attr_set = tc->mount_attrs;
89131

90-
TST_EXP_PASS_SILENT(mount_setattr(otfd, "", AT_EMPTY_PATH, &attr, sizeof(attr)),
91-
"%s set", tc->name);
92-
if (!TST_PASS)
93-
goto out1;
132+
otfd = tv->child_variant(attr);
133+
if (otfd == -1)
134+
goto out2;
94135

95136
TST_EXP_PASS_SILENT(move_mount(otfd, "", AT_FDCWD, OT_MNTPOINT, MOVE_MOUNT_F_EMPTY_PATH));
96137
if (!TST_PASS)
97138
goto out1;
139+
98140
mount_flag = 1;
99141
SAFE_CLOSE(otfd);
100142

101-
TST_EXP_PASS_SILENT(statvfs(OT_MNTPOINT, &buf), "statvfs sucess");
143+
TST_EXP_PASS_SILENT(statvfs(OT_MNTPOINT, &buf), "statvfs success");
102144
if (!TST_PASS)
103145
goto out2;
104146

@@ -123,9 +165,14 @@ static struct tst_test test = {
123165
.test = run,
124166
.setup = setup,
125167
.cleanup = cleanup,
168+
.test_variants = ARRAY_SIZE(tvariants),
126169
.needs_root = 1,
127170
.mount_device = 1,
128171
.mntpoint = MNTPOINT,
129172
.all_filesystems = 1,
130-
.skip_filesystems = (const char *const []){"fuse", NULL},
173+
.skip_filesystems = (const char *const []) {"fuse", NULL},
174+
.bufs = (struct tst_buffers []) {
175+
{&attr, .size = sizeof(struct mount_attr)},
176+
{}
177+
}
131178
};

0 commit comments

Comments
 (0)