1*49cdfc7eSAndroid Build Coastguard Worker /* SPDX-License-Identifier: GPL-2.0-or-later */
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2012-2020 Linux Test Project. All Rights Reserved.
4*49cdfc7eSAndroid Build Coastguard Worker * Author: Jan Kara, November 2013
5*49cdfc7eSAndroid Build Coastguard Worker */
6*49cdfc7eSAndroid Build Coastguard Worker
7*49cdfc7eSAndroid Build Coastguard Worker #ifndef __FANOTIFY_H__
8*49cdfc7eSAndroid Build Coastguard Worker #define __FANOTIFY_H__
9*49cdfc7eSAndroid Build Coastguard Worker
10*49cdfc7eSAndroid Build Coastguard Worker #include <sys/statfs.h>
11*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
12*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
13*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
14*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/fanotify.h"
15*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/fcntl.h"
16*49cdfc7eSAndroid Build Coastguard Worker
safe_fanotify_init(const char * file,const int lineno,unsigned int flags,unsigned int event_f_flags)17*49cdfc7eSAndroid Build Coastguard Worker static inline int safe_fanotify_init(const char *file, const int lineno,
18*49cdfc7eSAndroid Build Coastguard Worker unsigned int flags, unsigned int event_f_flags)
19*49cdfc7eSAndroid Build Coastguard Worker {
20*49cdfc7eSAndroid Build Coastguard Worker int rval;
21*49cdfc7eSAndroid Build Coastguard Worker
22*49cdfc7eSAndroid Build Coastguard Worker rval = fanotify_init(flags, event_f_flags);
23*49cdfc7eSAndroid Build Coastguard Worker
24*49cdfc7eSAndroid Build Coastguard Worker if (rval == -1) {
25*49cdfc7eSAndroid Build Coastguard Worker if (errno == ENOSYS) {
26*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TCONF,
27*49cdfc7eSAndroid Build Coastguard Worker "fanotify is not configured in this kernel");
28*49cdfc7eSAndroid Build Coastguard Worker }
29*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TBROK | TERRNO,
30*49cdfc7eSAndroid Build Coastguard Worker "%s:%d: fanotify_init() failed", file, lineno);
31*49cdfc7eSAndroid Build Coastguard Worker }
32*49cdfc7eSAndroid Build Coastguard Worker
33*49cdfc7eSAndroid Build Coastguard Worker if (rval < -1) {
34*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TBROK | TERRNO,
35*49cdfc7eSAndroid Build Coastguard Worker "invalid fanotify_init() return %d", rval);
36*49cdfc7eSAndroid Build Coastguard Worker }
37*49cdfc7eSAndroid Build Coastguard Worker
38*49cdfc7eSAndroid Build Coastguard Worker return rval;
39*49cdfc7eSAndroid Build Coastguard Worker }
40*49cdfc7eSAndroid Build Coastguard Worker
safe_fanotify_mark(const char * file,const int lineno,int fd,unsigned int flags,uint64_t mask,int dfd,const char * pathname)41*49cdfc7eSAndroid Build Coastguard Worker static inline int safe_fanotify_mark(const char *file, const int lineno,
42*49cdfc7eSAndroid Build Coastguard Worker int fd, unsigned int flags, uint64_t mask,
43*49cdfc7eSAndroid Build Coastguard Worker int dfd, const char *pathname)
44*49cdfc7eSAndroid Build Coastguard Worker {
45*49cdfc7eSAndroid Build Coastguard Worker int rval;
46*49cdfc7eSAndroid Build Coastguard Worker
47*49cdfc7eSAndroid Build Coastguard Worker rval = fanotify_mark(fd, flags, mask, dfd, pathname);
48*49cdfc7eSAndroid Build Coastguard Worker
49*49cdfc7eSAndroid Build Coastguard Worker if (rval == -1) {
50*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TBROK | TERRNO,
51*49cdfc7eSAndroid Build Coastguard Worker "fanotify_mark(%d, 0x%x, 0x%lx, ..., %s) failed",
52*49cdfc7eSAndroid Build Coastguard Worker fd, flags, mask, pathname);
53*49cdfc7eSAndroid Build Coastguard Worker }
54*49cdfc7eSAndroid Build Coastguard Worker
55*49cdfc7eSAndroid Build Coastguard Worker if (rval < -1) {
56*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TBROK | TERRNO,
57*49cdfc7eSAndroid Build Coastguard Worker "invalid fanotify_mark() return %d", rval);
58*49cdfc7eSAndroid Build Coastguard Worker }
59*49cdfc7eSAndroid Build Coastguard Worker
60*49cdfc7eSAndroid Build Coastguard Worker return rval;
61*49cdfc7eSAndroid Build Coastguard Worker }
62*49cdfc7eSAndroid Build Coastguard Worker
63*49cdfc7eSAndroid Build Coastguard Worker #define SAFE_FANOTIFY_MARK(fd, flags, mask, dfd, pathname) \
64*49cdfc7eSAndroid Build Coastguard Worker safe_fanotify_mark(__FILE__, __LINE__, (fd), (flags), (mask), (dfd), (pathname))
65*49cdfc7eSAndroid Build Coastguard Worker
66*49cdfc7eSAndroid Build Coastguard Worker #define SAFE_FANOTIFY_INIT(fan, mode) \
67*49cdfc7eSAndroid Build Coastguard Worker safe_fanotify_init(__FILE__, __LINE__, (fan), (mode))
68*49cdfc7eSAndroid Build Coastguard Worker
69*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_NAME_TO_HANDLE_AT
70*49cdfc7eSAndroid Build Coastguard Worker
71*49cdfc7eSAndroid Build Coastguard Worker /*
72*49cdfc7eSAndroid Build Coastguard Worker * Helper function used to obtain fsid and file_handle for a given path.
73*49cdfc7eSAndroid Build Coastguard Worker * Used by test files correlated to FAN_REPORT_FID functionality.
74*49cdfc7eSAndroid Build Coastguard Worker *
75*49cdfc7eSAndroid Build Coastguard Worker * Returns 0 if normal NFS file handles are supported.
76*49cdfc7eSAndroid Build Coastguard Worker * Returns AT_HANDLE_FID, if only non-decodeable file handles are supported.
77*49cdfc7eSAndroid Build Coastguard Worker */
fanotify_get_fid(const char * path,__kernel_fsid_t * fsid,struct file_handle * handle)78*49cdfc7eSAndroid Build Coastguard Worker static inline int fanotify_get_fid(const char *path, __kernel_fsid_t *fsid,
79*49cdfc7eSAndroid Build Coastguard Worker struct file_handle *handle)
80*49cdfc7eSAndroid Build Coastguard Worker {
81*49cdfc7eSAndroid Build Coastguard Worker int mount_id;
82*49cdfc7eSAndroid Build Coastguard Worker struct statfs stats;
83*49cdfc7eSAndroid Build Coastguard Worker
84*49cdfc7eSAndroid Build Coastguard Worker if (statfs(path, &stats) == -1)
85*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO,
86*49cdfc7eSAndroid Build Coastguard Worker "statfs(%s, ...) failed", path);
87*49cdfc7eSAndroid Build Coastguard Worker memcpy(fsid, &stats.f_fsid, sizeof(stats.f_fsid));
88*49cdfc7eSAndroid Build Coastguard Worker
89*49cdfc7eSAndroid Build Coastguard Worker if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) {
90*49cdfc7eSAndroid Build Coastguard Worker if (errno == EOPNOTSUPP) {
91*49cdfc7eSAndroid Build Coastguard Worker /* Try to request non-decodeable fid instead */
92*49cdfc7eSAndroid Build Coastguard Worker if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id,
93*49cdfc7eSAndroid Build Coastguard Worker AT_HANDLE_FID) == 0)
94*49cdfc7eSAndroid Build Coastguard Worker return AT_HANDLE_FID;
95*49cdfc7eSAndroid Build Coastguard Worker
96*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF,
97*49cdfc7eSAndroid Build Coastguard Worker "filesystem %s does not support file handles",
98*49cdfc7eSAndroid Build Coastguard Worker tst_device->fs_type);
99*49cdfc7eSAndroid Build Coastguard Worker }
100*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO,
101*49cdfc7eSAndroid Build Coastguard Worker "name_to_handle_at(AT_FDCWD, %s, ...) failed", path);
102*49cdfc7eSAndroid Build Coastguard Worker }
103*49cdfc7eSAndroid Build Coastguard Worker return 0;
104*49cdfc7eSAndroid Build Coastguard Worker }
105*49cdfc7eSAndroid Build Coastguard Worker
106*49cdfc7eSAndroid Build Coastguard Worker struct fanotify_fid_t {
107*49cdfc7eSAndroid Build Coastguard Worker __kernel_fsid_t fsid;
108*49cdfc7eSAndroid Build Coastguard Worker struct file_handle handle;
109*49cdfc7eSAndroid Build Coastguard Worker char buf[MAX_HANDLE_SZ];
110*49cdfc7eSAndroid Build Coastguard Worker };
111*49cdfc7eSAndroid Build Coastguard Worker
fanotify_save_fid(const char * path,struct fanotify_fid_t * fid)112*49cdfc7eSAndroid Build Coastguard Worker static inline int fanotify_save_fid(const char *path,
113*49cdfc7eSAndroid Build Coastguard Worker struct fanotify_fid_t *fid)
114*49cdfc7eSAndroid Build Coastguard Worker {
115*49cdfc7eSAndroid Build Coastguard Worker int *fh = (int *)(fid->handle.f_handle);
116*49cdfc7eSAndroid Build Coastguard Worker int ret;
117*49cdfc7eSAndroid Build Coastguard Worker
118*49cdfc7eSAndroid Build Coastguard Worker fh[0] = fh[1] = fh[2] = 0;
119*49cdfc7eSAndroid Build Coastguard Worker fid->handle.handle_bytes = MAX_HANDLE_SZ;
120*49cdfc7eSAndroid Build Coastguard Worker ret = fanotify_get_fid(path, &fid->fsid, &fid->handle);
121*49cdfc7eSAndroid Build Coastguard Worker
122*49cdfc7eSAndroid Build Coastguard Worker tst_res(TINFO,
123*49cdfc7eSAndroid Build Coastguard Worker "fid(%s) = %x.%x.%x.%x.%x...", path, fid->fsid.val[0],
124*49cdfc7eSAndroid Build Coastguard Worker fid->fsid.val[1], fh[0], fh[1], fh[2]);
125*49cdfc7eSAndroid Build Coastguard Worker
126*49cdfc7eSAndroid Build Coastguard Worker return ret;
127*49cdfc7eSAndroid Build Coastguard Worker }
128*49cdfc7eSAndroid Build Coastguard Worker #endif /* HAVE_NAME_TO_HANDLE_AT */
129*49cdfc7eSAndroid Build Coastguard Worker
130*49cdfc7eSAndroid Build Coastguard Worker #define INIT_FANOTIFY_GROUP_TYPE(t) \
131*49cdfc7eSAndroid Build Coastguard Worker { FAN_ ## t, "FAN_" #t }
132*49cdfc7eSAndroid Build Coastguard Worker
133*49cdfc7eSAndroid Build Coastguard Worker #define INIT_FANOTIFY_MARK_TYPE(t) \
134*49cdfc7eSAndroid Build Coastguard Worker { FAN_MARK_ ## t, "FAN_MARK_" #t }
135*49cdfc7eSAndroid Build Coastguard Worker
require_fanotify_access_permissions_supported_on_fs(const char * fname)136*49cdfc7eSAndroid Build Coastguard Worker static inline void require_fanotify_access_permissions_supported_on_fs(
137*49cdfc7eSAndroid Build Coastguard Worker const char *fname)
138*49cdfc7eSAndroid Build Coastguard Worker {
139*49cdfc7eSAndroid Build Coastguard Worker int fd;
140*49cdfc7eSAndroid Build Coastguard Worker
141*49cdfc7eSAndroid Build Coastguard Worker fd = SAFE_FANOTIFY_INIT(FAN_CLASS_CONTENT, O_RDONLY);
142*49cdfc7eSAndroid Build Coastguard Worker
143*49cdfc7eSAndroid Build Coastguard Worker if (fanotify_mark(fd, FAN_MARK_ADD, FAN_ACCESS_PERM, AT_FDCWD, fname) < 0) {
144*49cdfc7eSAndroid Build Coastguard Worker if (errno == EINVAL) {
145*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF | TERRNO,
146*49cdfc7eSAndroid Build Coastguard Worker "CONFIG_FANOTIFY_ACCESS_PERMISSIONS not configured in kernel?");
147*49cdfc7eSAndroid Build Coastguard Worker } else {
148*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO,
149*49cdfc7eSAndroid Build Coastguard Worker "fanotify_mark (%d, FAN_MARK_ADD, FAN_ACCESS_PERM, AT_FDCWD, \".\") failed", fd);
150*49cdfc7eSAndroid Build Coastguard Worker }
151*49cdfc7eSAndroid Build Coastguard Worker }
152*49cdfc7eSAndroid Build Coastguard Worker
153*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fd);
154*49cdfc7eSAndroid Build Coastguard Worker }
155*49cdfc7eSAndroid Build Coastguard Worker
156*49cdfc7eSAndroid Build Coastguard Worker /*
157*49cdfc7eSAndroid Build Coastguard Worker * @return 0: fanotify flags supported both in kernel and on tested filesystem
158*49cdfc7eSAndroid Build Coastguard Worker * @return -1: @init_flags not supported in kernel
159*49cdfc7eSAndroid Build Coastguard Worker * @return -2: @mark_flags not supported on tested filesystem (tested if @fname is not NULL)
160*49cdfc7eSAndroid Build Coastguard Worker * @return -3: @mark_flags not supported on overlayfs (tested if @fname == OVL_MNT)
161*49cdfc7eSAndroid Build Coastguard Worker */
fanotify_flags_supported_on_fs(unsigned int init_flags,unsigned int mark_flags,uint64_t event_flags,const char * fname)162*49cdfc7eSAndroid Build Coastguard Worker static inline int fanotify_flags_supported_on_fs(unsigned int init_flags,
163*49cdfc7eSAndroid Build Coastguard Worker unsigned int mark_flags,
164*49cdfc7eSAndroid Build Coastguard Worker uint64_t event_flags,
165*49cdfc7eSAndroid Build Coastguard Worker const char *fname)
166*49cdfc7eSAndroid Build Coastguard Worker {
167*49cdfc7eSAndroid Build Coastguard Worker int fd;
168*49cdfc7eSAndroid Build Coastguard Worker int rval = 0;
169*49cdfc7eSAndroid Build Coastguard Worker int err = 0;
170*49cdfc7eSAndroid Build Coastguard Worker
171*49cdfc7eSAndroid Build Coastguard Worker fd = fanotify_init(init_flags, O_RDONLY);
172*49cdfc7eSAndroid Build Coastguard Worker if (fd < 0) {
173*49cdfc7eSAndroid Build Coastguard Worker err = errno;
174*49cdfc7eSAndroid Build Coastguard Worker if (errno == ENOSYS)
175*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF, "fanotify not configured in kernel");
176*49cdfc7eSAndroid Build Coastguard Worker if (errno != EINVAL)
177*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO,
178*49cdfc7eSAndroid Build Coastguard Worker "fanotify_init(%x, O_RDONLY) failed",
179*49cdfc7eSAndroid Build Coastguard Worker init_flags);
180*49cdfc7eSAndroid Build Coastguard Worker errno = err;
181*49cdfc7eSAndroid Build Coastguard Worker return -1;
182*49cdfc7eSAndroid Build Coastguard Worker }
183*49cdfc7eSAndroid Build Coastguard Worker
184*49cdfc7eSAndroid Build Coastguard Worker if (fname && fanotify_mark(fd, FAN_MARK_ADD | mark_flags, event_flags, AT_FDCWD, fname) < 0) {
185*49cdfc7eSAndroid Build Coastguard Worker err = errno;
186*49cdfc7eSAndroid Build Coastguard Worker if (errno == ENODEV || errno == EOPNOTSUPP || errno == EXDEV) {
187*49cdfc7eSAndroid Build Coastguard Worker rval = strcmp(fname, OVL_MNT) ? -2 : -3;
188*49cdfc7eSAndroid Build Coastguard Worker } else if (errno != EINVAL) {
189*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO,
190*49cdfc7eSAndroid Build Coastguard Worker "fanotify_mark (%d, FAN_MARK_ADD | %x, %llx, AT_FDCWD, %s) failed",
191*49cdfc7eSAndroid Build Coastguard Worker fd, mark_flags, (unsigned long long)event_flags,
192*49cdfc7eSAndroid Build Coastguard Worker fname);
193*49cdfc7eSAndroid Build Coastguard Worker } else {
194*49cdfc7eSAndroid Build Coastguard Worker rval = -1;
195*49cdfc7eSAndroid Build Coastguard Worker }
196*49cdfc7eSAndroid Build Coastguard Worker }
197*49cdfc7eSAndroid Build Coastguard Worker
198*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fd);
199*49cdfc7eSAndroid Build Coastguard Worker
200*49cdfc7eSAndroid Build Coastguard Worker errno = err;
201*49cdfc7eSAndroid Build Coastguard Worker return rval;
202*49cdfc7eSAndroid Build Coastguard Worker }
203*49cdfc7eSAndroid Build Coastguard Worker
fanotify_init_flags_supported_on_fs(unsigned int flags,const char * fname)204*49cdfc7eSAndroid Build Coastguard Worker static inline int fanotify_init_flags_supported_on_fs(unsigned int flags, const char *fname)
205*49cdfc7eSAndroid Build Coastguard Worker {
206*49cdfc7eSAndroid Build Coastguard Worker return fanotify_flags_supported_on_fs(flags, FAN_MARK_INODE, FAN_ACCESS, fname);
207*49cdfc7eSAndroid Build Coastguard Worker }
208*49cdfc7eSAndroid Build Coastguard Worker
fanotify_mark_supported_on_fs(uint64_t flag,const char * fname)209*49cdfc7eSAndroid Build Coastguard Worker static inline int fanotify_mark_supported_on_fs(uint64_t flag, const char *fname)
210*49cdfc7eSAndroid Build Coastguard Worker {
211*49cdfc7eSAndroid Build Coastguard Worker return fanotify_flags_supported_on_fs(FAN_CLASS_NOTIF, flag, FAN_ACCESS, fname);
212*49cdfc7eSAndroid Build Coastguard Worker }
213*49cdfc7eSAndroid Build Coastguard Worker
214*49cdfc7eSAndroid Build Coastguard Worker #define TST_FANOTIFY_INIT_KNOWN_FLAGS \
215*49cdfc7eSAndroid Build Coastguard Worker (FAN_REPORT_DFID_NAME_TARGET | FAN_REPORT_TID | FAN_REPORT_PIDFD | \
216*49cdfc7eSAndroid Build Coastguard Worker FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | FAN_CLASS_PRE_CONTENT)
217*49cdfc7eSAndroid Build Coastguard Worker
218*49cdfc7eSAndroid Build Coastguard Worker /*
219*49cdfc7eSAndroid Build Coastguard Worker * Check support of given init flags one by one and return those which are
220*49cdfc7eSAndroid Build Coastguard Worker * supported.
221*49cdfc7eSAndroid Build Coastguard Worker */
fanotify_get_supported_init_flags(unsigned int flags,const char * fname)222*49cdfc7eSAndroid Build Coastguard Worker static inline unsigned int fanotify_get_supported_init_flags(unsigned int flags,
223*49cdfc7eSAndroid Build Coastguard Worker const char *fname)
224*49cdfc7eSAndroid Build Coastguard Worker {
225*49cdfc7eSAndroid Build Coastguard Worker unsigned int i, flg, arg, ret = 0;
226*49cdfc7eSAndroid Build Coastguard Worker static const struct { unsigned int flag, deps; } deplist[] = {
227*49cdfc7eSAndroid Build Coastguard Worker {FAN_REPORT_NAME, FAN_REPORT_DIR_FID},
228*49cdfc7eSAndroid Build Coastguard Worker {FAN_REPORT_TARGET_FID, FAN_REPORT_DFID_NAME_FID},
229*49cdfc7eSAndroid Build Coastguard Worker {0, 0}
230*49cdfc7eSAndroid Build Coastguard Worker };
231*49cdfc7eSAndroid Build Coastguard Worker
232*49cdfc7eSAndroid Build Coastguard Worker if (flags & ~TST_FANOTIFY_INIT_KNOWN_FLAGS) {
233*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK, "fanotify_init() feature check called with unknown flags %x, please update flag dependency table if needed",
234*49cdfc7eSAndroid Build Coastguard Worker flags & ~TST_FANOTIFY_INIT_KNOWN_FLAGS);
235*49cdfc7eSAndroid Build Coastguard Worker }
236*49cdfc7eSAndroid Build Coastguard Worker
237*49cdfc7eSAndroid Build Coastguard Worker for (flg = 1; flg; flg <<= 1) {
238*49cdfc7eSAndroid Build Coastguard Worker if (!(flags & flg))
239*49cdfc7eSAndroid Build Coastguard Worker continue;
240*49cdfc7eSAndroid Build Coastguard Worker
241*49cdfc7eSAndroid Build Coastguard Worker arg = flg;
242*49cdfc7eSAndroid Build Coastguard Worker
243*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; deplist[i].flag; i++) {
244*49cdfc7eSAndroid Build Coastguard Worker if (deplist[i].flag == flg) {
245*49cdfc7eSAndroid Build Coastguard Worker arg |= deplist[i].deps;
246*49cdfc7eSAndroid Build Coastguard Worker break;
247*49cdfc7eSAndroid Build Coastguard Worker }
248*49cdfc7eSAndroid Build Coastguard Worker }
249*49cdfc7eSAndroid Build Coastguard Worker
250*49cdfc7eSAndroid Build Coastguard Worker if (!fanotify_init_flags_supported_on_fs(arg, fname))
251*49cdfc7eSAndroid Build Coastguard Worker ret |= flg;
252*49cdfc7eSAndroid Build Coastguard Worker }
253*49cdfc7eSAndroid Build Coastguard Worker
254*49cdfc7eSAndroid Build Coastguard Worker return ret;
255*49cdfc7eSAndroid Build Coastguard Worker }
256*49cdfc7eSAndroid Build Coastguard Worker
257*49cdfc7eSAndroid Build Coastguard Worker typedef void (*tst_res_func_t)(const char *file, const int lineno,
258*49cdfc7eSAndroid Build Coastguard Worker int ttype, const char *fmt, ...);
259*49cdfc7eSAndroid Build Coastguard Worker
fanotify_flags_err_msg(const char * flags_str,const char * file,const int lineno,tst_res_func_t res_func,int fail)260*49cdfc7eSAndroid Build Coastguard Worker static inline void fanotify_flags_err_msg(const char *flags_str,
261*49cdfc7eSAndroid Build Coastguard Worker const char *file, const int lineno, tst_res_func_t res_func, int fail)
262*49cdfc7eSAndroid Build Coastguard Worker {
263*49cdfc7eSAndroid Build Coastguard Worker if (fail == -1)
264*49cdfc7eSAndroid Build Coastguard Worker res_func(file, lineno, TCONF,
265*49cdfc7eSAndroid Build Coastguard Worker "%s not supported in kernel?", flags_str);
266*49cdfc7eSAndroid Build Coastguard Worker if (fail == -2 || fail == -3)
267*49cdfc7eSAndroid Build Coastguard Worker res_func(file, lineno, TCONF,
268*49cdfc7eSAndroid Build Coastguard Worker "%s not supported on %s%s filesystem",
269*49cdfc7eSAndroid Build Coastguard Worker flags_str, fail == -3 ? "overlayfs over " : "",
270*49cdfc7eSAndroid Build Coastguard Worker tst_device->fs_type);
271*49cdfc7eSAndroid Build Coastguard Worker }
272*49cdfc7eSAndroid Build Coastguard Worker
273*49cdfc7eSAndroid Build Coastguard Worker #define FANOTIFY_INIT_FLAGS_ERR_MSG(flags, fail) \
274*49cdfc7eSAndroid Build Coastguard Worker fanotify_flags_err_msg(#flags, __FILE__, __LINE__, tst_res_, (fail))
275*49cdfc7eSAndroid Build Coastguard Worker
276*49cdfc7eSAndroid Build Coastguard Worker #define FANOTIFY_MARK_FLAGS_ERR_MSG(mark, fail) \
277*49cdfc7eSAndroid Build Coastguard Worker fanotify_flags_err_msg((mark)->name, __FILE__, __LINE__, tst_res_, (fail))
278*49cdfc7eSAndroid Build Coastguard Worker
279*49cdfc7eSAndroid Build Coastguard Worker #define REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(flags, fname) \
280*49cdfc7eSAndroid Build Coastguard Worker fanotify_flags_err_msg(#flags, __FILE__, __LINE__, tst_brk_, \
281*49cdfc7eSAndroid Build Coastguard Worker fanotify_init_flags_supported_on_fs(flags, fname))
282*49cdfc7eSAndroid Build Coastguard Worker
fanotify_handle_supported_by_kernel(int flag)283*49cdfc7eSAndroid Build Coastguard Worker static inline int fanotify_handle_supported_by_kernel(int flag)
284*49cdfc7eSAndroid Build Coastguard Worker {
285*49cdfc7eSAndroid Build Coastguard Worker /*
286*49cdfc7eSAndroid Build Coastguard Worker * On Kernel that does not support AT_HANDLE_FID this will result
287*49cdfc7eSAndroid Build Coastguard Worker * with EINVAL. On older kernels, this will result in EBADF.
288*49cdfc7eSAndroid Build Coastguard Worker */
289*49cdfc7eSAndroid Build Coastguard Worker if (name_to_handle_at(-1, "", NULL, NULL, AT_EMPTY_PATH | flag)) {
290*49cdfc7eSAndroid Build Coastguard Worker if (errno == EINVAL)
291*49cdfc7eSAndroid Build Coastguard Worker return -1;
292*49cdfc7eSAndroid Build Coastguard Worker }
293*49cdfc7eSAndroid Build Coastguard Worker return 0;
294*49cdfc7eSAndroid Build Coastguard Worker }
295*49cdfc7eSAndroid Build Coastguard Worker
296*49cdfc7eSAndroid Build Coastguard Worker #define REQUIRE_MARK_TYPE_SUPPORTED_ON_FS(mark_type, fname) \
297*49cdfc7eSAndroid Build Coastguard Worker fanotify_flags_err_msg(#mark_type, __FILE__, __LINE__, tst_brk_, \
298*49cdfc7eSAndroid Build Coastguard Worker fanotify_mark_supported_on_fs(mark_type, fname))
299*49cdfc7eSAndroid Build Coastguard Worker
300*49cdfc7eSAndroid Build Coastguard Worker #define REQUIRE_HANDLE_TYPE_SUPPORTED_BY_KERNEL(handle_type) \
301*49cdfc7eSAndroid Build Coastguard Worker fanotify_flags_err_msg(#handle_type, __FILE__, __LINE__, tst_brk_, \
302*49cdfc7eSAndroid Build Coastguard Worker fanotify_handle_supported_by_kernel(handle_type))
303*49cdfc7eSAndroid Build Coastguard Worker
304*49cdfc7eSAndroid Build Coastguard Worker #define REQUIRE_FANOTIFY_EVENTS_SUPPORTED_ON_FS(init_flags, mark_type, mask, fname) do { \
305*49cdfc7eSAndroid Build Coastguard Worker if (mark_type) \
306*49cdfc7eSAndroid Build Coastguard Worker REQUIRE_MARK_TYPE_SUPPORTED_ON_FS(mark_type, fname); \
307*49cdfc7eSAndroid Build Coastguard Worker if (init_flags) \
308*49cdfc7eSAndroid Build Coastguard Worker REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(init_flags, fname); \
309*49cdfc7eSAndroid Build Coastguard Worker fanotify_flags_err_msg(#mask, __FILE__, __LINE__, tst_brk_, \
310*49cdfc7eSAndroid Build Coastguard Worker fanotify_flags_supported_on_fs(init_flags, mark_type, mask, fname)); \
311*49cdfc7eSAndroid Build Coastguard Worker } while (0)
312*49cdfc7eSAndroid Build Coastguard Worker
get_event_info(struct fanotify_event_metadata * event,int info_type)313*49cdfc7eSAndroid Build Coastguard Worker static inline struct fanotify_event_info_header *get_event_info(
314*49cdfc7eSAndroid Build Coastguard Worker struct fanotify_event_metadata *event,
315*49cdfc7eSAndroid Build Coastguard Worker int info_type)
316*49cdfc7eSAndroid Build Coastguard Worker {
317*49cdfc7eSAndroid Build Coastguard Worker struct fanotify_event_info_header *hdr = NULL;
318*49cdfc7eSAndroid Build Coastguard Worker char *start = (char *) event;
319*49cdfc7eSAndroid Build Coastguard Worker int off;
320*49cdfc7eSAndroid Build Coastguard Worker
321*49cdfc7eSAndroid Build Coastguard Worker for (off = event->metadata_len; (off+sizeof(*hdr)) < event->event_len;
322*49cdfc7eSAndroid Build Coastguard Worker off += hdr->len) {
323*49cdfc7eSAndroid Build Coastguard Worker hdr = (struct fanotify_event_info_header *) &(start[off]);
324*49cdfc7eSAndroid Build Coastguard Worker if (hdr->info_type == info_type)
325*49cdfc7eSAndroid Build Coastguard Worker return hdr;
326*49cdfc7eSAndroid Build Coastguard Worker }
327*49cdfc7eSAndroid Build Coastguard Worker return NULL;
328*49cdfc7eSAndroid Build Coastguard Worker }
329*49cdfc7eSAndroid Build Coastguard Worker
330*49cdfc7eSAndroid Build Coastguard Worker #define get_event_info_error(event) \
331*49cdfc7eSAndroid Build Coastguard Worker ((struct fanotify_event_info_error *) \
332*49cdfc7eSAndroid Build Coastguard Worker get_event_info((event), FAN_EVENT_INFO_TYPE_ERROR))
333*49cdfc7eSAndroid Build Coastguard Worker
334*49cdfc7eSAndroid Build Coastguard Worker #define get_event_info_fid(event) \
335*49cdfc7eSAndroid Build Coastguard Worker ((struct fanotify_event_info_fid *) \
336*49cdfc7eSAndroid Build Coastguard Worker get_event_info((event), FAN_EVENT_INFO_TYPE_FID))
337*49cdfc7eSAndroid Build Coastguard Worker
338*49cdfc7eSAndroid Build Coastguard Worker #endif /* __FANOTIFY_H__ */
339