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:
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"
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+
4349static 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
4564static struct tcase {
4665 char * name ;
@@ -66,39 +85,62 @@ static void cleanup(void)
6685static 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+
75121static 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