1 //SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Referred from linux kernel -github/torvalds/linux/include/uapi/linux/fcntl.h
4 * Copyright (c) Zilogic Systems Pvt. Ltd., 2018
5 * Email: code@zilogic.com
6 */
7
8 #ifndef LAPI_STAT_H__
9 #define LAPI_STAT_H__
10
11 #include <stdint.h>
12 #include <unistd.h>
13 #include <sys/stat.h>
14 #include "lapi/syscalls.h"
15
16 /*
17 * Timestamp structure for the timestamps in struct statx.
18 *
19 * tv_sec holds the number of seconds before (negative) or after (positive)
20 * 00:00:00 1st January 1970 UTC.
21 *
22 * tv_nsec holds a number of nanoseconds (0..999,999,999) after the tv_sec time.
23 *
24 * __reserved is held in case we need a yet finer resolution.
25 */
26 #ifndef HAVE_STRUCT_STATX_TIMESTAMP
27 struct statx_timestamp {
28 int64_t tv_sec;
29 uint32_t tv_nsec;
30 int32_t __reserved;
31 };
32 #endif
33
34 /*
35 * Structures for the extended file attribute retrieval system call
36 * (statx()).
37 *
38 * The caller passes a mask of what they're specifically interested in as a
39 * parameter to statx(). What statx() actually got will be indicated in
40 * st_mask upon return.
41 *
42 * For each bit in the mask argument:
43 *
44 * - if the datum is not supported:
45 *
46 * - the bit will be cleared, and
47 *
48 * - the datum will be set to an appropriate fabricated value if one is
49 * available (eg. CIFS can take a default uid and gid), otherwise
50 *
51 * - the field will be cleared;
52 *
53 * - otherwise, if explicitly requested:
54 *
55 * - the datum will be synchronised to the server if AT_STATX_FORCE_SYNC is
56 * set or if the datum is considered out of date, and
57 *
58 * - the field will be filled in and the bit will be set;
59 *
60 * - otherwise, if not requested, but available in approximate form without any
61 * effort, it will be filled in anyway, and the bit will be set upon return
62 * (it might not be up to date, however, and no attempt will be made to
63 * synchronise the internal state first);
64 *
65 * - otherwise the field and the bit will be cleared before returning.
66 *
67 * Items in STATX_BASIC_STATS may be marked unavailable on return, but they
68 * will have values installed for compatibility purposes so that stat() and
69 * co. can be emulated in userspace.
70 */
71 #define LTP_DEFINE_STATX_STRUCT(x) \
72 struct x { \
73 uint32_t stx_mask; \
74 uint32_t stx_blksize; \
75 uint64_t stx_attributes; \
76 uint32_t stx_nlink; \
77 uint32_t stx_uid; \
78 uint32_t stx_gid; \
79 uint16_t stx_mode; \
80 uint16_t __spare0[1]; \
81 uint64_t stx_ino; \
82 uint64_t stx_size; \
83 uint64_t stx_blocks; \
84 uint64_t stx_attributes_mask; \
85 const struct statx_timestamp stx_atime; \
86 const struct statx_timestamp stx_btime; \
87 const struct statx_timestamp stx_ctime; \
88 const struct statx_timestamp stx_mtime; \
89 uint32_t stx_rdev_major; \
90 uint32_t stx_rdev_minor; \
91 uint32_t stx_dev_major; \
92 uint32_t stx_dev_minor; \
93 uint64_t stx_mnt_id; \
94 uint32_t stx_dio_mem_align; \
95 uint32_t stx_dio_offset_align; \
96 uint64_t __spare3[12]; \
97 };
98
99 LTP_DEFINE_STATX_STRUCT(statx_fallback);
100
101 #ifndef HAVE_STRUCT_STATX
102 LTP_DEFINE_STATX_STRUCT(statx);
103 #endif
104
105 /*
106 * This is the fallback statx that we pass to the safe_statx() syscall.
107 * The reason why we need it, is that statx struct is constantly changing
108 * inside the kernel and we need to extend its definition when structure
109 * changes in order to compile the tests.
110 */
111 struct ltp_statx {
112 union {
113 struct statx buff;
114 struct statx_fallback data;
115 };
116 };
117
118 #ifndef HAVE_STATX
119
120 /*
121 * statx: wrapper function of statx
122 *
123 * Returns: It returns status of statx syscall
124 */
statx(int dirfd,const char * pathname,unsigned int flags,unsigned int mask,struct statx * st)125 static inline int statx(int dirfd, const char *pathname, unsigned int flags,
126 unsigned int mask, struct statx *st)
127 {
128 return tst_syscall(__NR_statx, dirfd, pathname, flags, mask, st);
129 }
130 #endif
131
132 /*
133 * Flags to be stx_mask
134 *
135 * Query request/result mask for statx() and struct statx::stx_mask.
136 *
137 * These bits should be set in the mask argument of statx() to request
138 * particular items when calling statx().
139 */
140 #ifndef STATX_TYPE
141 # define STATX_TYPE 0x00000001U
142 #endif
143
144 #ifndef STATX_MODE
145 # define STATX_MODE 0x00000002U
146 #endif
147
148 #ifndef STATX_NLINK
149 # define STATX_NLINK 0x00000004U
150 #endif
151
152 #ifndef STATX_UID
153 # define STATX_UID 0x00000008U
154 #endif
155
156 #ifndef STATX_GID
157 # define STATX_GID 0x00000010U
158 #endif
159
160 #ifndef STATX_ATIME
161 # define STATX_ATIME 0x00000020U
162 #endif
163
164 #ifndef STATX_MTIME
165 # define STATX_MTIME 0x00000040U
166 #endif
167
168 #ifndef STATX_CTIME
169 # define STATX_CTIME 0x00000080U
170 #endif
171
172 #ifndef STATX_INO
173 # define STATX_INO 0x00000100U
174 #endif
175
176 #ifndef STATX_SIZE
177 # define STATX_SIZE 0x00000200U
178 #endif
179
180 #ifndef STATX_BLOCKS
181 # define STATX_BLOCKS 0x00000400U
182 #endif
183
184 #ifndef STATX_BASIC_STATS
185 # define STATX_BASIC_STATS 0x000007ffU
186 #endif
187
188 #ifndef STATX_BTIME
189 # define STATX_BTIME 0x00000800U
190 #endif
191
192 #ifndef STATX_MNT_ID
193 # define STATX_MNT_ID 0x00001000U
194 #endif
195
196 #ifndef STATX_DIOALIGN
197 # define STATX_DIOALIGN 0x00002000U
198 #endif
199
200 #ifndef STATX__RESERVED
201 # define STATX__RESERVED 0x80000000U
202 #endif
203
204 /*
205 * Attributes to be found in stx_attributes and masked in stx_attributes_mask.
206 *
207 * These give information about the features or the state of a file that might
208 * be of use to ordinary userspace programs such as GUIs or ls rather than
209 * specialised tools.
210 *
211 * Note that the flags marked [I] correspond to generic FS_IOC_FLAGS
212 * semantically. Where possible, the numerical value is picked to correspond
213 * also.
214 */
215 #ifndef STATX_ATTR_COMPRESSED
216 # define STATX_ATTR_COMPRESSED 0x00000004
217 #endif
218
219 #ifndef STATX_ATTR_IMMUTABLE
220 # define STATX_ATTR_IMMUTABLE 0x00000010
221 #endif
222
223 #ifndef STATX_ATTR_APPEND
224 # define STATX_ATTR_APPEND 0x00000020
225 #endif
226
227 #ifndef STATX_ATTR_NODUMP
228 # define STATX_ATTR_NODUMP 0x00000040
229 #endif
230
231 #ifndef STATX_ATTR_ENCRYPTED
232 # define STATX_ATTR_ENCRYPTED 0x00000800
233 #endif
234
235 #ifndef STATX_ATTR_AUTOMOUNT
236 # define STATX_ATTR_AUTOMOUNT 0x00001000
237 #endif
238
239 #ifndef STATX_ATTR_MOUNT_ROOT
240 # define STATX_ATTR_MOUNT_ROOT 0x00002000
241 #endif
242
243 #ifndef STATX_ATTR_VERITY
244 # define STATX_ATTR_VERITY 0x00100000
245 #endif
246
247 #ifndef STATX_MNT_ID_UNIQUE
248 # define STATX_MNT_ID_UNIQUE 0x00004000U
249 #endif
250
251 #define SAFE_FCHMODAT2(dfd, filename, mode, flags) \
252 safe_fchmodat2(__FILE__, __LINE__, (dfd), (filename), (mode), (flags))
253
safe_fchmodat2(const char * file,const int lineno,int dfd,const char * filename,mode_t mode,int flags)254 static inline int safe_fchmodat2(const char *file, const int lineno,
255 int dfd, const char *filename, mode_t mode, int flags)
256 {
257 int ret;
258
259 ret = tst_syscall(__NR_fchmodat2, dfd, filename, mode, flags);
260 if (ret == -1) {
261 tst_brk_(file, lineno, TBROK | TERRNO,
262 "syscall(__NR_fchmodat2,%d,%s,%d,%d) failed",
263 dfd, filename, mode, flags);
264 } else if (ret) {
265 tst_brk_(file, lineno, TBROK | TERRNO,
266 "Invalid syscall(__NR_fchmodat2,%d,%s,%d,%d) return value %d",
267 dfd, filename, mode, flags, ret);
268 }
269
270 return ret;
271 }
272
273 #define SAFE_STATX(dirfd, pathname, flags, mask, buf) \
274 safe_statx(__FILE__, __LINE__, (dirfd), (pathname), (flags), (mask), (buf))
275
safe_statx(const char * file,const int lineno,int dirfd,const char * pathname,int flags,unsigned int mask,struct ltp_statx * buf)276 static inline int safe_statx(const char *file, const int lineno,
277 int dirfd, const char *pathname, int flags, unsigned int mask,
278 struct ltp_statx *buf)
279 {
280 int rval;
281
282 rval = statx(dirfd, pathname, flags, mask, &buf->buff);
283
284 if (rval == -1) {
285 tst_brk_(file, lineno, TBROK | TERRNO,
286 "statx(%d,%s,%d,%u,%p) failed", dirfd, pathname, flags, mask, buf);
287 } else if (rval) {
288 tst_brk_(file, lineno, TBROK | TERRNO,
289 "Invalid statx(%d,%s,%d,%u,%p) return value %d",
290 dirfd, pathname, flags, mask, buf,
291 rval);
292 }
293
294 return rval;
295 }
296
297 #endif /* LAPI_STAT_H__ */
298