@@ -99,11 +99,64 @@ struct test_case {
99
99
};
100
100
101
101
static inline int sys_utimensat (int dirfd , const char * pathname ,
102
- const struct __kernel_old_timespec times [ 2 ] , int flags )
102
+ void * times , int flags )
103
103
{
104
104
return tst_syscall (__NR_utimensat , dirfd , pathname , times , flags );
105
105
}
106
106
107
+ static inline int sys_utimensat_time64 (int dirfd , const char * pathname ,
108
+ void * times , int flags )
109
+ {
110
+ return tst_syscall (__NR_utimensat_time64 , dirfd , pathname , times , flags );
111
+ }
112
+
113
+ static struct test_variants {
114
+ int (* utimensat )(int dirfd , const char * pathname , void * times ,
115
+ int flags );
116
+ enum tst_ts_type type ;
117
+ char * desc ;
118
+ } variants [] = {
119
+ #if (__NR_utimensat != __LTP__NR_INVALID_SYSCALL )
120
+ { .utimensat = sys_utimensat , .type = TST_KERN_OLD_TIMESPEC , .desc = "syscall with old kernel spec" },
121
+ #endif
122
+
123
+ #if (__NR_utimensat_time64 != __LTP__NR_INVALID_SYSCALL )
124
+ { .utimensat = sys_utimensat_time64 , .type = TST_KERN_TIMESPEC , .desc = "syscall time64 with kernel spec" },
125
+ #endif
126
+ };
127
+
128
+ union tst_multi {
129
+ struct timespec libc_ts [2 ];
130
+ struct __kernel_old_timespec kern_old_ts [2 ];
131
+ struct __kernel_timespec kern_ts [2 ];
132
+ } ts ;
133
+
134
+ static void tst_multi_set_time (enum tst_ts_type type , struct mytime * mytime )
135
+ {
136
+ switch (type ) {
137
+ case TST_LIBC_TIMESPEC :
138
+ ts .libc_ts [0 ].tv_sec = mytime -> access_tv_sec ;
139
+ ts .libc_ts [0 ].tv_nsec = mytime -> access_tv_nsec ;
140
+ ts .libc_ts [1 ].tv_sec = mytime -> mod_tv_sec ;
141
+ ts .libc_ts [1 ].tv_nsec = mytime -> mod_tv_nsec ;
142
+ break ;
143
+ case TST_KERN_OLD_TIMESPEC :
144
+ ts .kern_old_ts [0 ].tv_sec = mytime -> access_tv_sec ;
145
+ ts .kern_old_ts [0 ].tv_nsec = mytime -> access_tv_nsec ;
146
+ ts .kern_old_ts [1 ].tv_sec = mytime -> mod_tv_sec ;
147
+ ts .kern_old_ts [1 ].tv_nsec = mytime -> mod_tv_nsec ;
148
+ break ;
149
+ case TST_KERN_TIMESPEC :
150
+ ts .kern_ts [0 ].tv_sec = mytime -> access_tv_sec ;
151
+ ts .kern_ts [0 ].tv_nsec = mytime -> access_tv_nsec ;
152
+ ts .kern_ts [1 ].tv_sec = mytime -> mod_tv_sec ;
153
+ ts .kern_ts [1 ].tv_nsec = mytime -> mod_tv_nsec ;
154
+ break ;
155
+ default :
156
+ tst_brk (TBROK , "Invalid type: %d" , type );
157
+ }
158
+ }
159
+
107
160
static void update_error (struct test_case * tc )
108
161
{
109
162
if (tc -> exp_err != -1 )
@@ -140,11 +193,11 @@ static void change_attr(struct test_case *tc, int fd, int set)
140
193
141
194
static void reset_time (char * pathname , int dfd , int flags , int i )
142
195
{
143
- struct __kernel_old_timespec ts [ 2 ];
196
+ struct test_variants * tv = & variants [ tst_variant ];
144
197
struct stat sb ;
145
198
146
- memset (ts , 0 , sizeof (ts ));
147
- sys_utimensat (dfd , pathname , ts , flags );
199
+ memset (& ts , 0 , sizeof (ts ));
200
+ tv -> utimensat (dfd , pathname , & ts , flags );
148
201
149
202
TEST (stat (pathname , & sb ));
150
203
if (TST_RET ) {
@@ -157,8 +210,8 @@ static void reset_time(char *pathname, int dfd, int flags, int i)
157
210
158
211
static void run (unsigned int i )
159
212
{
213
+ struct test_variants * tv = & variants [tst_variant ];
160
214
struct test_case * tc = & tcase [i ];
161
- struct __kernel_old_timespec ts [2 ];
162
215
int dfd = AT_FDCWD , fd = 0 , atime_change , mtime_change ;
163
216
struct mytime * mytime = tc -> mytime ;
164
217
char * pathname = NULL ;
@@ -179,16 +232,13 @@ static void run(unsigned int i)
179
232
}
180
233
181
234
if (mytime ) {
182
- ts [0 ].tv_sec = mytime -> access_tv_sec ;
183
- ts [0 ].tv_nsec = mytime -> access_tv_nsec ;
184
- ts [1 ].tv_sec = mytime -> mod_tv_sec ;
185
- ts [1 ].tv_nsec = mytime -> mod_tv_nsec ;
186
- tsp = ts ;
235
+ tst_multi_set_time (tv -> type , mytime );
236
+ tsp = & ts ;
187
237
} else if (tc -> exp_err == EFAULT ) {
188
238
tsp = bad_addr ;
189
239
}
190
240
191
- TEST (sys_utimensat (dfd , pathname , tsp , tc -> flags ));
241
+ TEST (tv -> utimensat (dfd , pathname , tsp , tc -> flags ));
192
242
if (tc -> pathname )
193
243
change_attr (tc , fd , 0 );
194
244
@@ -238,6 +288,8 @@ static void setup(void)
238
288
{
239
289
size_t i ;
240
290
291
+ tst_res (TINFO , "Testing variant: %s" , variants [tst_variant ].desc );
292
+
241
293
bad_addr = tst_get_bad_addr (NULL );
242
294
SAFE_MKDIR (TEST_DIR , 0700 );
243
295
@@ -248,6 +300,7 @@ static void setup(void)
248
300
static struct tst_test test = {
249
301
.test = run ,
250
302
.tcnt = ARRAY_SIZE (tcase ),
303
+ .test_variants = ARRAY_SIZE (variants ),
251
304
.setup = setup ,
252
305
.needs_root = 1 ,
253
306
.needs_tmpdir = 1 ,
0 commit comments