xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/fanotify/fanotify16.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
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) 2020 CTERA Networks. All Rights Reserved.
4*49cdfc7eSAndroid Build Coastguard Worker  *
5*49cdfc7eSAndroid Build Coastguard Worker  * Started by Amir Goldstein <[email protected]>
6*49cdfc7eSAndroid Build Coastguard Worker  */
7*49cdfc7eSAndroid Build Coastguard Worker 
8*49cdfc7eSAndroid Build Coastguard Worker /*\
9*49cdfc7eSAndroid Build Coastguard Worker  * [Description]
10*49cdfc7eSAndroid Build Coastguard Worker  * Check fanotify directory entry modification events, events on child and
11*49cdfc7eSAndroid Build Coastguard Worker  * on self with group init flags:
12*49cdfc7eSAndroid Build Coastguard Worker  *
13*49cdfc7eSAndroid Build Coastguard Worker  * - FAN_REPORT_DFID_NAME (dir fid + name)
14*49cdfc7eSAndroid Build Coastguard Worker  * - FAN_REPORT_DIR_FID   (dir fid)
15*49cdfc7eSAndroid Build Coastguard Worker  * - FAN_REPORT_DIR_FID | FAN_REPORT_FID   (dir fid + child fid)
16*49cdfc7eSAndroid Build Coastguard Worker  * - FAN_REPORT_DFID_NAME | FAN_REPORT_FID (dir fid + name + child fid)
17*49cdfc7eSAndroid Build Coastguard Worker  * - FAN_REPORT_DFID_NAME_TARGET (dir fid + name + created/deleted file fid)
18*49cdfc7eSAndroid Build Coastguard Worker  */
19*49cdfc7eSAndroid Build Coastguard Worker 
20*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
21*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
22*49cdfc7eSAndroid Build Coastguard Worker 
23*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
24*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
25*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
26*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
27*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
28*49cdfc7eSAndroid Build Coastguard Worker #include <sys/mount.h>
29*49cdfc7eSAndroid Build Coastguard Worker #include <sys/syscall.h>
30*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
31*49cdfc7eSAndroid Build Coastguard Worker 
32*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_SYS_FANOTIFY_H
33*49cdfc7eSAndroid Build Coastguard Worker #include "fanotify.h"
34*49cdfc7eSAndroid Build Coastguard Worker 
35*49cdfc7eSAndroid Build Coastguard Worker #define EVENT_MAX 20
36*49cdfc7eSAndroid Build Coastguard Worker 
37*49cdfc7eSAndroid Build Coastguard Worker /* Size of the event structure, not including file handle */
38*49cdfc7eSAndroid Build Coastguard Worker #define EVENT_SIZE (sizeof(struct fanotify_event_metadata) + \
39*49cdfc7eSAndroid Build Coastguard Worker 		    sizeof(struct fanotify_event_info_fid))
40*49cdfc7eSAndroid Build Coastguard Worker 
41*49cdfc7eSAndroid Build Coastguard Worker /* Tripple events buffer size to account for file handles and names */
42*49cdfc7eSAndroid Build Coastguard Worker #define EVENT_BUF_LEN (EVENT_MAX * EVENT_SIZE * 3)
43*49cdfc7eSAndroid Build Coastguard Worker 
44*49cdfc7eSAndroid Build Coastguard Worker #define BUF_SIZE 256
45*49cdfc7eSAndroid Build Coastguard Worker 
46*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_NAME_TO_HANDLE_AT
47*49cdfc7eSAndroid Build Coastguard Worker struct event_t {
48*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long long mask;
49*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_fid_t *fid;
50*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_fid_t *child_fid;
51*49cdfc7eSAndroid Build Coastguard Worker 	char name[BUF_SIZE];
52*49cdfc7eSAndroid Build Coastguard Worker 	char name2[BUF_SIZE];
53*49cdfc7eSAndroid Build Coastguard Worker 	char *old_name;
54*49cdfc7eSAndroid Build Coastguard Worker 	char *new_name;
55*49cdfc7eSAndroid Build Coastguard Worker };
56*49cdfc7eSAndroid Build Coastguard Worker 
57*49cdfc7eSAndroid Build Coastguard Worker static char fname1[BUF_SIZE + 11], fname2[BUF_SIZE + 11];
58*49cdfc7eSAndroid Build Coastguard Worker static char dname1[BUF_SIZE], dname2[BUF_SIZE], tmpdir[BUF_SIZE];
59*49cdfc7eSAndroid Build Coastguard Worker static int fd_notify;
60*49cdfc7eSAndroid Build Coastguard Worker 
61*49cdfc7eSAndroid Build Coastguard Worker static struct event_t event_set[EVENT_MAX];
62*49cdfc7eSAndroid Build Coastguard Worker 
63*49cdfc7eSAndroid Build Coastguard Worker static char event_buf[EVENT_BUF_LEN];
64*49cdfc7eSAndroid Build Coastguard Worker 
65*49cdfc7eSAndroid Build Coastguard Worker #define DIR_NAME1 "test_dir1"
66*49cdfc7eSAndroid Build Coastguard Worker #define DIR_NAME2 "test_dir2"
67*49cdfc7eSAndroid Build Coastguard Worker #define FILE_NAME1 "test_file1"
68*49cdfc7eSAndroid Build Coastguard Worker #define FILE_NAME2 "test_file2"
69*49cdfc7eSAndroid Build Coastguard Worker #define MOUNT_PATH "fs_mnt"
70*49cdfc7eSAndroid Build Coastguard Worker #define TEMP_DIR MOUNT_PATH "/temp_dir"
71*49cdfc7eSAndroid Build Coastguard Worker 
72*49cdfc7eSAndroid Build Coastguard Worker static int fan_report_target_fid_unsupported;
73*49cdfc7eSAndroid Build Coastguard Worker static int filesystem_mark_unsupported;
74*49cdfc7eSAndroid Build Coastguard Worker static int rename_events_unsupported;
75*49cdfc7eSAndroid Build Coastguard Worker 
76*49cdfc7eSAndroid Build Coastguard Worker static struct test_case_t {
77*49cdfc7eSAndroid Build Coastguard Worker 	const char *tname;
78*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_group_type group;
79*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_mark_type mark;
80*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long mask;
81*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_mark_type sub_mark;
82*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long sub_mask;
83*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long tmpdir_ignored_mask;
84*49cdfc7eSAndroid Build Coastguard Worker } test_cases[] = {
85*49cdfc7eSAndroid Build Coastguard Worker 	{
86*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME monitor filesystem for create/delete/move/open/close",
87*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME),
88*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
89*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR,
90*49cdfc7eSAndroid Build Coastguard Worker 		/* Mount watch for events possible on children */
91*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(MOUNT),
92*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_ONDIR,
93*49cdfc7eSAndroid Build Coastguard Worker 		0,
94*49cdfc7eSAndroid Build Coastguard Worker 	},
95*49cdfc7eSAndroid Build Coastguard Worker 	{
96*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME monitor directories for create/delete/move/open/close",
97*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME),
98*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
99*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_ONDIR,
100*49cdfc7eSAndroid Build Coastguard Worker 		/* Watches for self events on subdir and events on subdir's children */
101*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
102*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR |
103*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_EVENT_ON_CHILD,
104*49cdfc7eSAndroid Build Coastguard Worker 		0,
105*49cdfc7eSAndroid Build Coastguard Worker 	},
106*49cdfc7eSAndroid Build Coastguard Worker 	{
107*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DIR_FID monitor filesystem for create/delete/move/open/close",
108*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DIR_FID),
109*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
110*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR,
111*49cdfc7eSAndroid Build Coastguard Worker 		/* Mount watch for events possible on children */
112*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(MOUNT),
113*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_ONDIR,
114*49cdfc7eSAndroid Build Coastguard Worker 		0,
115*49cdfc7eSAndroid Build Coastguard Worker 	},
116*49cdfc7eSAndroid Build Coastguard Worker 	{
117*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DIR_FID monitor directories for create/delete/move/open/close",
118*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DIR_FID),
119*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
120*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_ONDIR,
121*49cdfc7eSAndroid Build Coastguard Worker 		/* Watches for self events on subdir and events on subdir's children */
122*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
123*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR |
124*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_EVENT_ON_CHILD,
125*49cdfc7eSAndroid Build Coastguard Worker 		0,
126*49cdfc7eSAndroid Build Coastguard Worker 	},
127*49cdfc7eSAndroid Build Coastguard Worker 	{
128*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_FID monitor filesystem for create/delete/move/open/close",
129*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_FID),
130*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
131*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR,
132*49cdfc7eSAndroid Build Coastguard Worker 		/* Mount watch for events possible on children */
133*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(MOUNT),
134*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_ONDIR,
135*49cdfc7eSAndroid Build Coastguard Worker 		0,
136*49cdfc7eSAndroid Build Coastguard Worker 	},
137*49cdfc7eSAndroid Build Coastguard Worker 	{
138*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_FID monitor directories for create/delete/move/open/close",
139*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_FID),
140*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
141*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_ONDIR,
142*49cdfc7eSAndroid Build Coastguard Worker 		/* Watches for self events on subdir and events on subdir's children */
143*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
144*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR |
145*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_EVENT_ON_CHILD,
146*49cdfc7eSAndroid Build Coastguard Worker 		0,
147*49cdfc7eSAndroid Build Coastguard Worker 	},
148*49cdfc7eSAndroid Build Coastguard Worker 	{
149*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME_FID monitor filesystem for create/delete/move/open/close",
150*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME_FID),
151*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
152*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR,
153*49cdfc7eSAndroid Build Coastguard Worker 		/* Mount watch for events possible on children */
154*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(MOUNT),
155*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_ONDIR,
156*49cdfc7eSAndroid Build Coastguard Worker 		0,
157*49cdfc7eSAndroid Build Coastguard Worker 	},
158*49cdfc7eSAndroid Build Coastguard Worker 	{
159*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME_FID monitor directories for create/delete/move/open/close",
160*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME_FID),
161*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
162*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_ONDIR,
163*49cdfc7eSAndroid Build Coastguard Worker 		/* Watches for self events on subdir and events on subdir's children */
164*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
165*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR |
166*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_EVENT_ON_CHILD,
167*49cdfc7eSAndroid Build Coastguard Worker 		0,
168*49cdfc7eSAndroid Build Coastguard Worker 	},
169*49cdfc7eSAndroid Build Coastguard Worker 	{
170*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME_TARGET monitor filesystem for create/delete/move/open/close",
171*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME_TARGET),
172*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
173*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR,
174*49cdfc7eSAndroid Build Coastguard Worker 		/* Mount watch for events possible on children */
175*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(MOUNT),
176*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_ONDIR,
177*49cdfc7eSAndroid Build Coastguard Worker 		0,
178*49cdfc7eSAndroid Build Coastguard Worker 	},
179*49cdfc7eSAndroid Build Coastguard Worker 	{
180*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME_TARGET monitor directories for create/delete/move/open/close",
181*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME_TARGET),
182*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
183*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_ONDIR,
184*49cdfc7eSAndroid Build Coastguard Worker 		/* Watches for self events on subdir and events on subdir's children */
185*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
186*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR |
187*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_EVENT_ON_CHILD,
188*49cdfc7eSAndroid Build Coastguard Worker 		0,
189*49cdfc7eSAndroid Build Coastguard Worker 	},
190*49cdfc7eSAndroid Build Coastguard Worker 	{
191*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME_FID monitor filesystem for create/delete/move/rename/open/close",
192*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME_FID),
193*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
194*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_RENAME | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR,
195*49cdfc7eSAndroid Build Coastguard Worker 		/* Mount watch for events possible on children */
196*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(MOUNT),
197*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_ONDIR,
198*49cdfc7eSAndroid Build Coastguard Worker 		0,
199*49cdfc7eSAndroid Build Coastguard Worker 	},
200*49cdfc7eSAndroid Build Coastguard Worker 	{
201*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME_FID monitor directories for create/delete/move/rename/open/close",
202*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME_FID),
203*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
204*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_RENAME | FAN_ONDIR,
205*49cdfc7eSAndroid Build Coastguard Worker 		/* Watches for self events on subdir and events on subdir's children */
206*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
207*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_RENAME | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR |
208*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_EVENT_ON_CHILD,
209*49cdfc7eSAndroid Build Coastguard Worker 		0,
210*49cdfc7eSAndroid Build Coastguard Worker 	},
211*49cdfc7eSAndroid Build Coastguard Worker 	{
212*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME_TARGET monitor filesystem for create/delete/move/rename/open/close",
213*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME_TARGET),
214*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
215*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_RENAME | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR,
216*49cdfc7eSAndroid Build Coastguard Worker 		/* Mount watch for events possible on children */
217*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(MOUNT),
218*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_ONDIR,
219*49cdfc7eSAndroid Build Coastguard Worker 		0,
220*49cdfc7eSAndroid Build Coastguard Worker 	},
221*49cdfc7eSAndroid Build Coastguard Worker 	{
222*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME_TARGET monitor directories for create/delete/move/rename/open/close",
223*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME_TARGET),
224*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
225*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_RENAME | FAN_ONDIR,
226*49cdfc7eSAndroid Build Coastguard Worker 		/* Watches for self events on subdir and events on subdir's children */
227*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
228*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_RENAME | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR |
229*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_EVENT_ON_CHILD,
230*49cdfc7eSAndroid Build Coastguard Worker 		0,
231*49cdfc7eSAndroid Build Coastguard Worker 	},
232*49cdfc7eSAndroid Build Coastguard Worker 	{
233*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME_FID monitor directories and ignore FAN_RENAME events to/from temp directory",
234*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME_FID),
235*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
236*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_RENAME | FAN_ONDIR,
237*49cdfc7eSAndroid Build Coastguard Worker 		/* Watches for self events on subdir and events on subdir's children */
238*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(INODE),
239*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_RENAME | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR |
240*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_EVENT_ON_CHILD,
241*49cdfc7eSAndroid Build Coastguard Worker 		/* Ignore FAN_RENAME to/from tmpdir */
242*49cdfc7eSAndroid Build Coastguard Worker 		FAN_MOVE | FAN_RENAME,
243*49cdfc7eSAndroid Build Coastguard Worker 	},
244*49cdfc7eSAndroid Build Coastguard Worker 	{
245*49cdfc7eSAndroid Build Coastguard Worker 		"FAN_REPORT_DFID_NAME_FID monitor filesystem and ignore FAN_RENAME events to/from temp directory",
246*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_GROUP_TYPE(REPORT_DFID_NAME_FID),
247*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
248*49cdfc7eSAndroid Build Coastguard Worker 		FAN_CREATE | FAN_DELETE | FAN_MOVE | FAN_RENAME | FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR,
249*49cdfc7eSAndroid Build Coastguard Worker 		/* Mount watch for events possible on children */
250*49cdfc7eSAndroid Build Coastguard Worker 		INIT_FANOTIFY_MARK_TYPE(MOUNT),
251*49cdfc7eSAndroid Build Coastguard Worker 		FAN_OPEN | FAN_CLOSE | FAN_ONDIR,
252*49cdfc7eSAndroid Build Coastguard Worker 		/* Ignore FAN_RENAME to/from tmpdir */
253*49cdfc7eSAndroid Build Coastguard Worker 		FAN_MOVE | FAN_RENAME,
254*49cdfc7eSAndroid Build Coastguard Worker 	},
255*49cdfc7eSAndroid Build Coastguard Worker };
256*49cdfc7eSAndroid Build Coastguard Worker 
do_test(unsigned int number)257*49cdfc7eSAndroid Build Coastguard Worker static void do_test(unsigned int number)
258*49cdfc7eSAndroid Build Coastguard Worker {
259*49cdfc7eSAndroid Build Coastguard Worker 	int fd, dirfd, len = 0, i = 0, test_num = 0, tst_count = 0;
260*49cdfc7eSAndroid Build Coastguard Worker 	struct test_case_t *tc = &test_cases[number];
261*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_group_type *group = &tc->group;
262*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_mark_type *mark = &tc->mark;
263*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_mark_type *sub_mark = &tc->sub_mark;
264*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_fid_t root_fid, dir_fid, file_fid;
265*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_fid_t *child_fid = NULL, *subdir_fid = NULL;
266*49cdfc7eSAndroid Build Coastguard Worker 	int report_name = (group->flag & FAN_REPORT_NAME);
267*49cdfc7eSAndroid Build Coastguard Worker 	int report_target_fid = (group->flag & FAN_REPORT_TARGET_FID);
268*49cdfc7eSAndroid Build Coastguard Worker 	int report_rename = (tc->mask & FAN_RENAME);
269*49cdfc7eSAndroid Build Coastguard Worker 	int fs_mark = (mark->flag == FAN_MARK_FILESYSTEM);
270*49cdfc7eSAndroid Build Coastguard Worker 	int rename_ignored = (tc->tmpdir_ignored_mask & FAN_RENAME);
271*49cdfc7eSAndroid Build Coastguard Worker 
272*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "Test #%d: %s", number, tc->tname);
273*49cdfc7eSAndroid Build Coastguard Worker 
274*49cdfc7eSAndroid Build Coastguard Worker 	if (report_rename && rename_events_unsupported) {
275*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TCONF, "FAN_RENAME not supported in kernel?");
276*49cdfc7eSAndroid Build Coastguard Worker 		return;
277*49cdfc7eSAndroid Build Coastguard Worker 	}
278*49cdfc7eSAndroid Build Coastguard Worker 
279*49cdfc7eSAndroid Build Coastguard Worker 	if (fan_report_target_fid_unsupported && report_target_fid) {
280*49cdfc7eSAndroid Build Coastguard Worker 		FANOTIFY_INIT_FLAGS_ERR_MSG(FAN_REPORT_TARGET_FID,
281*49cdfc7eSAndroid Build Coastguard Worker 					    fan_report_target_fid_unsupported);
282*49cdfc7eSAndroid Build Coastguard Worker 		return;
283*49cdfc7eSAndroid Build Coastguard Worker 	}
284*49cdfc7eSAndroid Build Coastguard Worker 
285*49cdfc7eSAndroid Build Coastguard Worker 	if (filesystem_mark_unsupported) {
286*49cdfc7eSAndroid Build Coastguard Worker 		if (sub_mark && sub_mark->flag != FAN_MARK_INODE)
287*49cdfc7eSAndroid Build Coastguard Worker 			mark = sub_mark;
288*49cdfc7eSAndroid Build Coastguard Worker 
289*49cdfc7eSAndroid Build Coastguard Worker 		if (mark->flag != FAN_MARK_INODE) {
290*49cdfc7eSAndroid Build Coastguard Worker 			FANOTIFY_MARK_FLAGS_ERR_MSG(mark, filesystem_mark_unsupported);
291*49cdfc7eSAndroid Build Coastguard Worker 			return;
292*49cdfc7eSAndroid Build Coastguard Worker 		}
293*49cdfc7eSAndroid Build Coastguard Worker 	}
294*49cdfc7eSAndroid Build Coastguard Worker 
295*49cdfc7eSAndroid Build Coastguard Worker 	fd_notify = SAFE_FANOTIFY_INIT(group->flag, 0);
296*49cdfc7eSAndroid Build Coastguard Worker 
297*49cdfc7eSAndroid Build Coastguard Worker 	/*
298*49cdfc7eSAndroid Build Coastguard Worker 	 * Watch dir modify events with name in filesystem/dir
299*49cdfc7eSAndroid Build Coastguard Worker 	 */
300*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_ADD | mark->flag, tc->mask,
301*49cdfc7eSAndroid Build Coastguard Worker 			   AT_FDCWD, MOUNT_PATH);
302*49cdfc7eSAndroid Build Coastguard Worker 
303*49cdfc7eSAndroid Build Coastguard Worker 	/* Save the mount root fid */
304*49cdfc7eSAndroid Build Coastguard Worker 	fanotify_save_fid(MOUNT_PATH, &root_fid);
305*49cdfc7eSAndroid Build Coastguard Worker 
306*49cdfc7eSAndroid Build Coastguard Worker 	/*
307*49cdfc7eSAndroid Build Coastguard Worker 	 * Create subdir and watch open events "on children" with name.
308*49cdfc7eSAndroid Build Coastguard Worker 	 * Make it a mount root.
309*49cdfc7eSAndroid Build Coastguard Worker 	 */
310*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_MKDIR(dname1, 0755);
311*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_MOUNT(dname1, dname1, "none", MS_BIND, NULL);
312*49cdfc7eSAndroid Build Coastguard Worker 
313*49cdfc7eSAndroid Build Coastguard Worker 	/* Save the subdir fid */
314*49cdfc7eSAndroid Build Coastguard Worker 	fanotify_save_fid(dname1, &dir_fid);
315*49cdfc7eSAndroid Build Coastguard Worker 	/* With FAN_REPORT_TARGET_FID, report subdir fid also for dirent events */
316*49cdfc7eSAndroid Build Coastguard Worker 	if (report_target_fid)
317*49cdfc7eSAndroid Build Coastguard Worker 		subdir_fid = &dir_fid;
318*49cdfc7eSAndroid Build Coastguard Worker 
319*49cdfc7eSAndroid Build Coastguard Worker 	if (tc->sub_mask)
320*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_ADD | sub_mark->flag,
321*49cdfc7eSAndroid Build Coastguard Worker 				   tc->sub_mask, AT_FDCWD, dname1);
322*49cdfc7eSAndroid Build Coastguard Worker 	/*
323*49cdfc7eSAndroid Build Coastguard Worker 	 * ignore FAN_RENAME to/from tmpdir, so we won't get the FAN_RENAME events
324*49cdfc7eSAndroid Build Coastguard Worker 	 * when subdir is moved via tmpdir.
325*49cdfc7eSAndroid Build Coastguard Worker 	 * FAN_MOVE is also set in ignored mark of tmpdir, but it will have no effect
326*49cdfc7eSAndroid Build Coastguard Worker 	 * and the MOVED_FROM/TO events will still be reported.
327*49cdfc7eSAndroid Build Coastguard Worker 	 */
328*49cdfc7eSAndroid Build Coastguard Worker 	if (tc->tmpdir_ignored_mask)
329*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_ADD |
330*49cdfc7eSAndroid Build Coastguard Worker 				   FAN_MARK_IGNORED_MASK |
331*49cdfc7eSAndroid Build Coastguard Worker 				   FAN_MARK_IGNORED_SURV_MODIFY,
332*49cdfc7eSAndroid Build Coastguard Worker 				   tc->tmpdir_ignored_mask, AT_FDCWD, TEMP_DIR);
333*49cdfc7eSAndroid Build Coastguard Worker 
334*49cdfc7eSAndroid Build Coastguard Worker 	memset(event_set, 0, sizeof(event_set));
335*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].mask = FAN_CREATE | FAN_ONDIR;
336*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].fid = &root_fid;
337*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].child_fid = subdir_fid;
338*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(event_set[tst_count].name, DIR_NAME1);
339*49cdfc7eSAndroid Build Coastguard Worker 	tst_count++;
340*49cdfc7eSAndroid Build Coastguard Worker 
341*49cdfc7eSAndroid Build Coastguard Worker 	/* Generate modify events "on child" */
342*49cdfc7eSAndroid Build Coastguard Worker 
343*49cdfc7eSAndroid Build Coastguard Worker 	/*
344*49cdfc7eSAndroid Build Coastguard Worker 	 * Split SAFE_CREAT() into explicit SAFE_MKNOD() and SAFE_OPEN(),
345*49cdfc7eSAndroid Build Coastguard Worker 	 * because with atomic open (e.g. fuse), SAFE_CREAT() generates
346*49cdfc7eSAndroid Build Coastguard Worker 	 * FAN_OPEN before FAN_CREATE and it is inconsistent with the order
347*49cdfc7eSAndroid Build Coastguard Worker 	 * of events expectated from other filesystems.
348*49cdfc7eSAndroid Build Coastguard Worker 	 */
349*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_MKNOD(fname1, S_IFREG | 0644, 0);
350*49cdfc7eSAndroid Build Coastguard Worker 	fd = SAFE_OPEN(fname1, O_WRONLY);
351*49cdfc7eSAndroid Build Coastguard Worker 
352*49cdfc7eSAndroid Build Coastguard Worker 	/* Save the file fid */
353*49cdfc7eSAndroid Build Coastguard Worker 	fanotify_save_fid(fname1, &file_fid);
354*49cdfc7eSAndroid Build Coastguard Worker 	/* With FAN_REPORT_TARGET_FID, report child fid also for dirent events */
355*49cdfc7eSAndroid Build Coastguard Worker 	if (report_target_fid)
356*49cdfc7eSAndroid Build Coastguard Worker 		child_fid = &file_fid;
357*49cdfc7eSAndroid Build Coastguard Worker 
358*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_WRITE(SAFE_WRITE_ALL, fd, "1", 1);
359*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_RENAME(fname1, fname2);
360*49cdfc7eSAndroid Build Coastguard Worker 
361*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CLOSE(fd);
362*49cdfc7eSAndroid Build Coastguard Worker 
363*49cdfc7eSAndroid Build Coastguard Worker 	/* Generate delete events with fname2 */
364*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_UNLINK(fname2);
365*49cdfc7eSAndroid Build Coastguard Worker 
366*49cdfc7eSAndroid Build Coastguard Worker 	/* Read events on files in subdir */
367*49cdfc7eSAndroid Build Coastguard Worker 	len += SAFE_READ(0, fd_notify, event_buf + len, EVENT_BUF_LEN - len);
368*49cdfc7eSAndroid Build Coastguard Worker 
369*49cdfc7eSAndroid Build Coastguard Worker 	/*
370*49cdfc7eSAndroid Build Coastguard Worker 	 * FAN_CREATE|FAN_DELETE|FAN_MOVE events with the same name are merged.
371*49cdfc7eSAndroid Build Coastguard Worker 	 */
372*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].mask = FAN_CREATE | FAN_MOVED_FROM;
373*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].fid = &dir_fid;
374*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].child_fid = child_fid;
375*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(event_set[tst_count].name, FILE_NAME1);
376*49cdfc7eSAndroid Build Coastguard Worker 	tst_count++;
377*49cdfc7eSAndroid Build Coastguard Worker 	/*
378*49cdfc7eSAndroid Build Coastguard Worker 	 * Event on non-dir child with the same name may be merged with the
379*49cdfc7eSAndroid Build Coastguard Worker 	 * directory entry modification events above, unless FAN_REPORT_FID is
380*49cdfc7eSAndroid Build Coastguard Worker 	 * set and child fid is reported. If FAN_REPORT_FID is set but
381*49cdfc7eSAndroid Build Coastguard Worker 	 * FAN_REPORT_NAME is not set, then FAN_CREATE above is merged with
382*49cdfc7eSAndroid Build Coastguard Worker 	 * FAN_DELETE below and FAN_OPEN will be merged with FAN_CLOSE.
383*49cdfc7eSAndroid Build Coastguard Worker 	 */
384*49cdfc7eSAndroid Build Coastguard Worker 	if (report_name) {
385*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].mask = FAN_OPEN;
386*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].fid = &dir_fid;
387*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].child_fid = &file_fid;
388*49cdfc7eSAndroid Build Coastguard Worker 		strcpy(event_set[tst_count].name, FILE_NAME1);
389*49cdfc7eSAndroid Build Coastguard Worker 		tst_count++;
390*49cdfc7eSAndroid Build Coastguard Worker 	}
391*49cdfc7eSAndroid Build Coastguard Worker 	/*
392*49cdfc7eSAndroid Build Coastguard Worker 	 * FAN_RENAME event is independent of MOVED_FROM/MOVED_TO and not merged
393*49cdfc7eSAndroid Build Coastguard Worker 	 * with any other event because it has different info records.
394*49cdfc7eSAndroid Build Coastguard Worker 	 */
395*49cdfc7eSAndroid Build Coastguard Worker 	if (report_rename) {
396*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].mask = FAN_RENAME;
397*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].fid = &dir_fid;
398*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].child_fid = child_fid;
399*49cdfc7eSAndroid Build Coastguard Worker 		strcpy(event_set[tst_count].name, FILE_NAME1);
400*49cdfc7eSAndroid Build Coastguard Worker 		strcpy(event_set[tst_count].name2, FILE_NAME2);
401*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].old_name = event_set[tst_count].name;
402*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].new_name = event_set[tst_count].name2;
403*49cdfc7eSAndroid Build Coastguard Worker 		tst_count++;
404*49cdfc7eSAndroid Build Coastguard Worker 	}
405*49cdfc7eSAndroid Build Coastguard Worker 
406*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].mask = FAN_DELETE | FAN_MOVED_TO;
407*49cdfc7eSAndroid Build Coastguard Worker 	/*
408*49cdfc7eSAndroid Build Coastguard Worker 	 * With FAN_REPORT_TARGET_FID, close of FILE_NAME2 is merged with
409*49cdfc7eSAndroid Build Coastguard Worker 	 * moved_to and delete events, because they all have parent and
410*49cdfc7eSAndroid Build Coastguard Worker 	 * child fid records.
411*49cdfc7eSAndroid Build Coastguard Worker 	 */
412*49cdfc7eSAndroid Build Coastguard Worker 	if (report_target_fid)
413*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].mask |= FAN_CLOSE_WRITE;
414*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].fid = &dir_fid;
415*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].child_fid = child_fid;
416*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(event_set[tst_count].name, FILE_NAME2);
417*49cdfc7eSAndroid Build Coastguard Worker 	tst_count++;
418*49cdfc7eSAndroid Build Coastguard Worker 	/*
419*49cdfc7eSAndroid Build Coastguard Worker 	 * When not reporting name, open of FILE_NAME1 is merged
420*49cdfc7eSAndroid Build Coastguard Worker 	 * with close of FILE_NAME2.
421*49cdfc7eSAndroid Build Coastguard Worker 	 */
422*49cdfc7eSAndroid Build Coastguard Worker 	if (!report_name) {
423*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].mask = FAN_OPEN | FAN_CLOSE_WRITE;
424*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].fid = &dir_fid;
425*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].child_fid = &file_fid;
426*49cdfc7eSAndroid Build Coastguard Worker 		strcpy(event_set[tst_count].name, "");
427*49cdfc7eSAndroid Build Coastguard Worker 		tst_count++;
428*49cdfc7eSAndroid Build Coastguard Worker 	}
429*49cdfc7eSAndroid Build Coastguard Worker 	/*
430*49cdfc7eSAndroid Build Coastguard Worker 	 * Directory watch does not get self events on children.
431*49cdfc7eSAndroid Build Coastguard Worker 	 * Filesystem watch gets self event w/o name info if FAN_REPORT_FID
432*49cdfc7eSAndroid Build Coastguard Worker 	 * is set.
433*49cdfc7eSAndroid Build Coastguard Worker 	 */
434*49cdfc7eSAndroid Build Coastguard Worker 	if (fs_mark && (group->flag & FAN_REPORT_FID)) {
435*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].mask = FAN_DELETE_SELF | FAN_MOVE_SELF;
436*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].fid = &file_fid;
437*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].child_fid = NULL;
438*49cdfc7eSAndroid Build Coastguard Worker 		strcpy(event_set[tst_count].name, "");
439*49cdfc7eSAndroid Build Coastguard Worker 		tst_count++;
440*49cdfc7eSAndroid Build Coastguard Worker 	}
441*49cdfc7eSAndroid Build Coastguard Worker 	/*
442*49cdfc7eSAndroid Build Coastguard Worker 	 * Without FAN_REPORT_TARGET_FID, close of FILE_NAME2 is not merged with
443*49cdfc7eSAndroid Build Coastguard Worker 	 * open of FILE_NAME1 and it is received after the merged self events.
444*49cdfc7eSAndroid Build Coastguard Worker 	 */
445*49cdfc7eSAndroid Build Coastguard Worker 	if (report_name && !report_target_fid) {
446*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].mask = FAN_CLOSE_WRITE;
447*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].fid = &dir_fid;
448*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].child_fid = &file_fid;
449*49cdfc7eSAndroid Build Coastguard Worker 		strcpy(event_set[tst_count].name, FILE_NAME2);
450*49cdfc7eSAndroid Build Coastguard Worker 		tst_count++;
451*49cdfc7eSAndroid Build Coastguard Worker 	}
452*49cdfc7eSAndroid Build Coastguard Worker 
453*49cdfc7eSAndroid Build Coastguard Worker 	dirfd = SAFE_OPEN(dname1, O_RDONLY | O_DIRECTORY);
454*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CLOSE(dirfd);
455*49cdfc7eSAndroid Build Coastguard Worker 
456*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_UMOUNT(dname1);
457*49cdfc7eSAndroid Build Coastguard Worker 
458*49cdfc7eSAndroid Build Coastguard Worker 	/*
459*49cdfc7eSAndroid Build Coastguard Worker 	 * Directory watch gets open/close events on itself and on its subdirs.
460*49cdfc7eSAndroid Build Coastguard Worker 	 * Filesystem watch gets open/close event on all directories with name ".".
461*49cdfc7eSAndroid Build Coastguard Worker 	 */
462*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].mask = FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR;
463*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].fid = &dir_fid;
464*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].child_fid = NULL;
465*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(event_set[tst_count].name, ".");
466*49cdfc7eSAndroid Build Coastguard Worker 	tst_count++;
467*49cdfc7eSAndroid Build Coastguard Worker 	/*
468*49cdfc7eSAndroid Build Coastguard Worker 	 * Directory watch gets self event on itself and filesystem watch gets
469*49cdfc7eSAndroid Build Coastguard Worker 	 * self event on all directories with name ".".
470*49cdfc7eSAndroid Build Coastguard Worker 	 */
471*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].mask = FAN_DELETE_SELF | FAN_MOVE_SELF | FAN_ONDIR;
472*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].fid = &dir_fid;
473*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].child_fid = NULL;
474*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(event_set[tst_count].name, ".");
475*49cdfc7eSAndroid Build Coastguard Worker 	tst_count++;
476*49cdfc7eSAndroid Build Coastguard Worker 
477*49cdfc7eSAndroid Build Coastguard Worker 	/*
478*49cdfc7eSAndroid Build Coastguard Worker 	 * If only root dir and subdir are watched, a rename via an unwatched tmpdir
479*49cdfc7eSAndroid Build Coastguard Worker 	 * will observe the same MOVED_FROM/MOVED_TO events as a direct rename,
480*49cdfc7eSAndroid Build Coastguard Worker 	 * but will observe 2 FAN_RENAME events with 1 info dir+name record each
481*49cdfc7eSAndroid Build Coastguard Worker 	 * instead of 1 FAN_RENAME event with 2 dir+name info records.
482*49cdfc7eSAndroid Build Coastguard Worker 	 *
483*49cdfc7eSAndroid Build Coastguard Worker 	 * If tmpdir is ignoring FAN_RENAME, we will get the MOVED_FROM/MOVED_TO
484*49cdfc7eSAndroid Build Coastguard Worker 	 * events and will not get the FAN_RENAME event for rename via tmpdir.
485*49cdfc7eSAndroid Build Coastguard Worker 	 */
486*49cdfc7eSAndroid Build Coastguard Worker 	if (!fs_mark || rename_ignored) {
487*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_RENAME(dname1, tmpdir);
488*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_RENAME(tmpdir, dname2);
489*49cdfc7eSAndroid Build Coastguard Worker 	} else {
490*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_RENAME(dname1, dname2);
491*49cdfc7eSAndroid Build Coastguard Worker 	}
492*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_RMDIR(dname2);
493*49cdfc7eSAndroid Build Coastguard Worker 
494*49cdfc7eSAndroid Build Coastguard Worker 	/* Read more events on dirs */
495*49cdfc7eSAndroid Build Coastguard Worker 	len += SAFE_READ(0, fd_notify, event_buf + len, EVENT_BUF_LEN - len);
496*49cdfc7eSAndroid Build Coastguard Worker 
497*49cdfc7eSAndroid Build Coastguard Worker 	/*
498*49cdfc7eSAndroid Build Coastguard Worker 	 * FAN_RENAME event is independent of MOVED_FROM/MOVED_TO and not merged
499*49cdfc7eSAndroid Build Coastguard Worker 	 * with any other event because it has different info records.
500*49cdfc7eSAndroid Build Coastguard Worker 	 * When renamed via an unwatched tmpdir, the 1st FAN_RENAME event has the
501*49cdfc7eSAndroid Build Coastguard Worker 	 * info record of root_fid+DIR_NAME1 and the 2nd FAN_RENAME event has the
502*49cdfc7eSAndroid Build Coastguard Worker 	 * info record of root_fid+DIR_NAME2.
503*49cdfc7eSAndroid Build Coastguard Worker 	 * If tmpdir is ignoring FAN_RENAME, we get no FAN_RENAME events at all.
504*49cdfc7eSAndroid Build Coastguard Worker 	 */
505*49cdfc7eSAndroid Build Coastguard Worker 	if (report_rename && !rename_ignored) {
506*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].mask = FAN_RENAME | FAN_ONDIR;
507*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].fid = &root_fid;
508*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].child_fid = subdir_fid;
509*49cdfc7eSAndroid Build Coastguard Worker 		strcpy(event_set[tst_count].name, DIR_NAME1);
510*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].old_name = event_set[tst_count].name;
511*49cdfc7eSAndroid Build Coastguard Worker 		if (fs_mark) {
512*49cdfc7eSAndroid Build Coastguard Worker 			strcpy(event_set[tst_count].name2, DIR_NAME2);
513*49cdfc7eSAndroid Build Coastguard Worker 			event_set[tst_count].new_name = event_set[tst_count].name2;
514*49cdfc7eSAndroid Build Coastguard Worker 		}
515*49cdfc7eSAndroid Build Coastguard Worker 		tst_count++;
516*49cdfc7eSAndroid Build Coastguard Worker 	}
517*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].mask = FAN_MOVED_FROM | FAN_ONDIR;
518*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].fid = &root_fid;
519*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].child_fid = subdir_fid;
520*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(event_set[tst_count].name, DIR_NAME1);
521*49cdfc7eSAndroid Build Coastguard Worker 	tst_count++;
522*49cdfc7eSAndroid Build Coastguard Worker 	if (report_rename && !fs_mark && !rename_ignored) {
523*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].mask = FAN_RENAME | FAN_ONDIR;
524*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].fid = &root_fid;
525*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].child_fid = subdir_fid;
526*49cdfc7eSAndroid Build Coastguard Worker 		strcpy(event_set[tst_count].name, DIR_NAME2);
527*49cdfc7eSAndroid Build Coastguard Worker 		event_set[tst_count].new_name = event_set[tst_count].name;
528*49cdfc7eSAndroid Build Coastguard Worker 		tst_count++;
529*49cdfc7eSAndroid Build Coastguard Worker 	}
530*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].mask = FAN_DELETE | FAN_MOVED_TO | FAN_ONDIR;
531*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].fid = &root_fid;
532*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].child_fid = subdir_fid;
533*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(event_set[tst_count].name, DIR_NAME2);
534*49cdfc7eSAndroid Build Coastguard Worker 	tst_count++;
535*49cdfc7eSAndroid Build Coastguard Worker 	/* Expect no more events */
536*49cdfc7eSAndroid Build Coastguard Worker 	event_set[tst_count].mask = 0;
537*49cdfc7eSAndroid Build Coastguard Worker 
538*49cdfc7eSAndroid Build Coastguard Worker 	/*
539*49cdfc7eSAndroid Build Coastguard Worker 	 * Cleanup the marks
540*49cdfc7eSAndroid Build Coastguard Worker 	 */
541*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CLOSE(fd_notify);
542*49cdfc7eSAndroid Build Coastguard Worker 	fd_notify = -1;
543*49cdfc7eSAndroid Build Coastguard Worker 
544*49cdfc7eSAndroid Build Coastguard Worker 	while (i < len) {
545*49cdfc7eSAndroid Build Coastguard Worker 		struct event_t *expected = &event_set[test_num];
546*49cdfc7eSAndroid Build Coastguard Worker 		struct fanotify_event_metadata *event;
547*49cdfc7eSAndroid Build Coastguard Worker 		struct fanotify_event_info_fid *event_fid;
548*49cdfc7eSAndroid Build Coastguard Worker 		struct fanotify_event_info_fid *child_fid;
549*49cdfc7eSAndroid Build Coastguard Worker 		struct fanotify_fid_t *expected_fid = expected->fid;
550*49cdfc7eSAndroid Build Coastguard Worker 		struct fanotify_fid_t *expected_child_fid = expected->child_fid;
551*49cdfc7eSAndroid Build Coastguard Worker 		struct file_handle *file_handle;
552*49cdfc7eSAndroid Build Coastguard Worker 		unsigned int fhlen;
553*49cdfc7eSAndroid Build Coastguard Worker 		const char *filename;
554*49cdfc7eSAndroid Build Coastguard Worker 		int namelen, info_type, mask_match, info_id = 0;
555*49cdfc7eSAndroid Build Coastguard Worker 
556*49cdfc7eSAndroid Build Coastguard Worker 		event = (struct fanotify_event_metadata *)&event_buf[i];
557*49cdfc7eSAndroid Build Coastguard Worker 		event_fid = (struct fanotify_event_info_fid *)(event + 1);
558*49cdfc7eSAndroid Build Coastguard Worker 		file_handle = (struct file_handle *)event_fid->handle;
559*49cdfc7eSAndroid Build Coastguard Worker 		fhlen = file_handle->handle_bytes;
560*49cdfc7eSAndroid Build Coastguard Worker 		filename = (char *)file_handle->f_handle + fhlen;
561*49cdfc7eSAndroid Build Coastguard Worker 		child_fid = (void *)((char *)event_fid + event_fid->hdr.len);
562*49cdfc7eSAndroid Build Coastguard Worker 		namelen = (char *)child_fid - (char *)filename;
563*49cdfc7eSAndroid Build Coastguard Worker 		/* End of event_fid could have name, zero padding, both or none */
564*49cdfc7eSAndroid Build Coastguard Worker 		if (namelen > 0) {
565*49cdfc7eSAndroid Build Coastguard Worker 			namelen = strlen(filename);
566*49cdfc7eSAndroid Build Coastguard Worker 		} else {
567*49cdfc7eSAndroid Build Coastguard Worker 			filename = "";
568*49cdfc7eSAndroid Build Coastguard Worker 			namelen = 0;
569*49cdfc7eSAndroid Build Coastguard Worker 		}
570*49cdfc7eSAndroid Build Coastguard Worker 		/* Is there a child fid after first fid record? */
571*49cdfc7eSAndroid Build Coastguard Worker 		if (((char *)child_fid - (char *)event) >= event->event_len)
572*49cdfc7eSAndroid Build Coastguard Worker 			child_fid = NULL;
573*49cdfc7eSAndroid Build Coastguard Worker 
574*49cdfc7eSAndroid Build Coastguard Worker 		if (!(group->flag & FAN_REPORT_FID))
575*49cdfc7eSAndroid Build Coastguard Worker 			expected_child_fid = NULL;
576*49cdfc7eSAndroid Build Coastguard Worker 
577*49cdfc7eSAndroid Build Coastguard Worker 		if (!report_name)
578*49cdfc7eSAndroid Build Coastguard Worker 			expected->name[0] = 0;
579*49cdfc7eSAndroid Build Coastguard Worker 
580*49cdfc7eSAndroid Build Coastguard Worker 		if (expected->mask & FAN_RENAME) {
581*49cdfc7eSAndroid Build Coastguard Worker 			/* If old name is not reported, first record is new name */
582*49cdfc7eSAndroid Build Coastguard Worker 			info_type = expected->old_name ?
583*49cdfc7eSAndroid Build Coastguard Worker 				FAN_EVENT_INFO_TYPE_OLD_DFID_NAME :
584*49cdfc7eSAndroid Build Coastguard Worker 				FAN_EVENT_INFO_TYPE_NEW_DFID_NAME;
585*49cdfc7eSAndroid Build Coastguard Worker 			/* The 2nd fid is same as 1st becaue we rename in same parent */
586*49cdfc7eSAndroid Build Coastguard Worker 			if (expected->name2[0])
587*49cdfc7eSAndroid Build Coastguard Worker 				expected_child_fid = expected_fid;
588*49cdfc7eSAndroid Build Coastguard Worker 		} else if (expected->name[0]) {
589*49cdfc7eSAndroid Build Coastguard Worker 			info_type = FAN_EVENT_INFO_TYPE_DFID_NAME;
590*49cdfc7eSAndroid Build Coastguard Worker 		} else if (expected->mask & FAN_ONDIR) {
591*49cdfc7eSAndroid Build Coastguard Worker 			info_type = FAN_EVENT_INFO_TYPE_DFID;
592*49cdfc7eSAndroid Build Coastguard Worker 		} else if (expected->mask & (FAN_DELETE_SELF | FAN_MOVE_SELF)) {
593*49cdfc7eSAndroid Build Coastguard Worker 			/* Self event on non-dir has only child fid */
594*49cdfc7eSAndroid Build Coastguard Worker 			info_type = FAN_EVENT_INFO_TYPE_FID;
595*49cdfc7eSAndroid Build Coastguard Worker 		} else {
596*49cdfc7eSAndroid Build Coastguard Worker 			info_type = FAN_EVENT_INFO_TYPE_DFID;
597*49cdfc7eSAndroid Build Coastguard Worker 		}
598*49cdfc7eSAndroid Build Coastguard Worker 
599*49cdfc7eSAndroid Build Coastguard Worker 		/*
600*49cdfc7eSAndroid Build Coastguard Worker 		 * Event may contain more than the expected mask, but it must
601*49cdfc7eSAndroid Build Coastguard Worker 		 * have all the bits in expected mask.
602*49cdfc7eSAndroid Build Coastguard Worker 		 * Expected event on dir must not get event on non dir and the
603*49cdfc7eSAndroid Build Coastguard Worker 		 * other way around.
604*49cdfc7eSAndroid Build Coastguard Worker 		 */
605*49cdfc7eSAndroid Build Coastguard Worker 		mask_match = ((event->mask & expected->mask) &&
606*49cdfc7eSAndroid Build Coastguard Worker 			      !(expected->mask & ~event->mask) &&
607*49cdfc7eSAndroid Build Coastguard Worker 			      !((event->mask ^ expected->mask) & FAN_ONDIR));
608*49cdfc7eSAndroid Build Coastguard Worker 
609*49cdfc7eSAndroid Build Coastguard Worker check_match:
610*49cdfc7eSAndroid Build Coastguard Worker 		if (test_num >= tst_count) {
611*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
612*49cdfc7eSAndroid Build Coastguard Worker 				"got unnecessary event: mask=%llx "
613*49cdfc7eSAndroid Build Coastguard Worker 				"pid=%u fd=%d name='%s' "
614*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d info_len=%d fh_len=%d",
615*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask,
616*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd, filename,
617*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, event_fid->hdr.info_type,
618*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen);
619*49cdfc7eSAndroid Build Coastguard Worker 		} else if (!fhlen || namelen < 0) {
620*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
621*49cdfc7eSAndroid Build Coastguard Worker 				"got event without fid: mask=%llx pid=%u fd=%d, "
622*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d info_len=%d fh_len=%d",
623*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask,
624*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd,
625*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, event_fid->hdr.info_type,
626*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen);
627*49cdfc7eSAndroid Build Coastguard Worker 		} else if (!mask_match) {
628*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
629*49cdfc7eSAndroid Build Coastguard Worker 				"got event: mask=%llx (expected %llx) "
630*49cdfc7eSAndroid Build Coastguard Worker 				"pid=%u fd=%d name='%s' "
631*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d info_len=%d fh_len=%d",
632*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask, expected->mask,
633*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd, filename,
634*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, event_fid->hdr.info_type,
635*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen);
636*49cdfc7eSAndroid Build Coastguard Worker 		} else if (info_type != event_fid->hdr.info_type) {
637*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
638*49cdfc7eSAndroid Build Coastguard Worker 				"got event: mask=%llx pid=%u fd=%d, "
639*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d expected(%d) info_len=%d fh_len=%d",
640*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask,
641*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd,
642*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, event_fid->hdr.info_type,
643*49cdfc7eSAndroid Build Coastguard Worker 				info_type, event_fid->hdr.len, fhlen);
644*49cdfc7eSAndroid Build Coastguard Worker 		} else if (fhlen != expected_fid->handle.handle_bytes) {
645*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
646*49cdfc7eSAndroid Build Coastguard Worker 				"got event: mask=%llx pid=%u fd=%d name='%s' "
647*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d info_len=%d fh_len=%d expected(%d) "
648*49cdfc7eSAndroid Build Coastguard Worker 				"fh_type=%d",
649*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask,
650*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd, filename,
651*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, info_type,
652*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen,
653*49cdfc7eSAndroid Build Coastguard Worker 				expected_fid->handle.handle_bytes,
654*49cdfc7eSAndroid Build Coastguard Worker 				file_handle->handle_type);
655*49cdfc7eSAndroid Build Coastguard Worker 		} else if (file_handle->handle_type !=
656*49cdfc7eSAndroid Build Coastguard Worker 			   expected_fid->handle.handle_type) {
657*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
658*49cdfc7eSAndroid Build Coastguard Worker 				"got event: mask=%llx pid=%u fd=%d name='%s' "
659*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d info_len=%d fh_len=%d "
660*49cdfc7eSAndroid Build Coastguard Worker 				"fh_type=%d expected(%x)",
661*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask,
662*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd, filename,
663*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, info_type,
664*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen,
665*49cdfc7eSAndroid Build Coastguard Worker 				file_handle->handle_type,
666*49cdfc7eSAndroid Build Coastguard Worker 				expected_fid->handle.handle_type);
667*49cdfc7eSAndroid Build Coastguard Worker 		} else if (memcmp(file_handle->f_handle,
668*49cdfc7eSAndroid Build Coastguard Worker 				  expected_fid->handle.f_handle, fhlen)) {
669*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
670*49cdfc7eSAndroid Build Coastguard Worker 				"got event: mask=%llx pid=%u fd=%d name='%s' "
671*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d info_len=%d fh_len=%d "
672*49cdfc7eSAndroid Build Coastguard Worker 				"fh_type=%d unexpected file handle (%x...)",
673*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask,
674*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd, filename,
675*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, info_type,
676*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen,
677*49cdfc7eSAndroid Build Coastguard Worker 				file_handle->handle_type,
678*49cdfc7eSAndroid Build Coastguard Worker 				*(int *)(file_handle->f_handle));
679*49cdfc7eSAndroid Build Coastguard Worker 		} else if (memcmp(&event_fid->fsid, &expected_fid->fsid,
680*49cdfc7eSAndroid Build Coastguard Worker 				  sizeof(event_fid->fsid)) != 0) {
681*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
682*49cdfc7eSAndroid Build Coastguard Worker 				"got event: mask=%llx pid=%u fd=%d name='%s' "
683*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d info_len=%d fh_len=%d "
684*49cdfc7eSAndroid Build Coastguard Worker 				"fsid=%x.%x (expected %x.%x)",
685*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask,
686*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd, filename,
687*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, info_type,
688*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen,
689*49cdfc7eSAndroid Build Coastguard Worker 				FSID_VAL_MEMBER(event_fid->fsid, 0),
690*49cdfc7eSAndroid Build Coastguard Worker 				FSID_VAL_MEMBER(event_fid->fsid, 1),
691*49cdfc7eSAndroid Build Coastguard Worker 				expected_fid->fsid.val[0],
692*49cdfc7eSAndroid Build Coastguard Worker 				expected_fid->fsid.val[1]);
693*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(expected->name, filename)) {
694*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
695*49cdfc7eSAndroid Build Coastguard Worker 				"got event: mask=%llx "
696*49cdfc7eSAndroid Build Coastguard Worker 				"pid=%u fd=%d name='%s' expected('%s') "
697*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d info_len=%d fh_len=%d",
698*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask,
699*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd,
700*49cdfc7eSAndroid Build Coastguard Worker 				filename, expected->name,
701*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, event_fid->hdr.info_type,
702*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen);
703*49cdfc7eSAndroid Build Coastguard Worker 		} else if (event->pid != getpid()) {
704*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
705*49cdfc7eSAndroid Build Coastguard Worker 				"got event: mask=%llx pid=%u "
706*49cdfc7eSAndroid Build Coastguard Worker 				"(expected %u) fd=%d name='%s' "
707*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d info_len=%d fh_len=%d",
708*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask,
709*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid,
710*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)getpid(),
711*49cdfc7eSAndroid Build Coastguard Worker 				event->fd, filename,
712*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, event_fid->hdr.info_type,
713*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen);
714*49cdfc7eSAndroid Build Coastguard Worker 		} else if (!!child_fid != !!expected_child_fid) {
715*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
716*49cdfc7eSAndroid Build Coastguard Worker 				"got event: mask=%llx "
717*49cdfc7eSAndroid Build Coastguard Worker 				"pid=%u fd=%d name='%s' num_info=%d (expected %d) "
718*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d info_type=%d info_len=%d fh_len=%d",
719*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned long long)event->mask,
720*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd,
721*49cdfc7eSAndroid Build Coastguard Worker 				filename, 1 + !!child_fid, 1 + !!expected_child_fid,
722*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, event_fid->hdr.info_type,
723*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen);
724*49cdfc7eSAndroid Build Coastguard Worker 		} else if (child_fid) {
725*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TINFO,
726*49cdfc7eSAndroid Build Coastguard Worker 				"got event #%d: info #%d: info_type=%d info_len=%d fh_len=%d",
727*49cdfc7eSAndroid Build Coastguard Worker 				test_num, info_id, event_fid->hdr.info_type,
728*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen);
729*49cdfc7eSAndroid Build Coastguard Worker 
730*49cdfc7eSAndroid Build Coastguard Worker 			/* Recheck event_fid match with child_fid */
731*49cdfc7eSAndroid Build Coastguard Worker 			event_fid = child_fid;
732*49cdfc7eSAndroid Build Coastguard Worker 			expected_fid = expected->child_fid;
733*49cdfc7eSAndroid Build Coastguard Worker 			info_id = 1;
734*49cdfc7eSAndroid Build Coastguard Worker 			info_type = FAN_EVENT_INFO_TYPE_FID;
735*49cdfc7eSAndroid Build Coastguard Worker 			/*
736*49cdfc7eSAndroid Build Coastguard Worker 			 * With FAN_RENAME event, expect a second record of
737*49cdfc7eSAndroid Build Coastguard Worker 			 * type NEW_DFID_NAME, which in our case
738*49cdfc7eSAndroid Build Coastguard Worker 			 * has the same fid as the source dir in 1st record.
739*49cdfc7eSAndroid Build Coastguard Worker 			 * TODO: check the 2nd name and the 3rd child fid record.
740*49cdfc7eSAndroid Build Coastguard Worker 			 */
741*49cdfc7eSAndroid Build Coastguard Worker 			if (event->mask & FAN_RENAME && expected->name2[0]) {
742*49cdfc7eSAndroid Build Coastguard Worker 				info_type = FAN_EVENT_INFO_TYPE_NEW_DFID_NAME;
743*49cdfc7eSAndroid Build Coastguard Worker 				expected_fid = expected->fid;
744*49cdfc7eSAndroid Build Coastguard Worker 			}
745*49cdfc7eSAndroid Build Coastguard Worker 			file_handle = (struct file_handle *)event_fid->handle;
746*49cdfc7eSAndroid Build Coastguard Worker 			fhlen = file_handle->handle_bytes;
747*49cdfc7eSAndroid Build Coastguard Worker 			child_fid = NULL;
748*49cdfc7eSAndroid Build Coastguard Worker 			expected_child_fid = NULL;
749*49cdfc7eSAndroid Build Coastguard Worker 			goto check_match;
750*49cdfc7eSAndroid Build Coastguard Worker 		} else {
751*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TPASS,
752*49cdfc7eSAndroid Build Coastguard Worker 				"got event #%d: mask=%llx pid=%u fd=%d name='%s' "
753*49cdfc7eSAndroid Build Coastguard Worker 				"len=%d; info #%d: info_type=%d info_len=%d fh_len=%d",
754*49cdfc7eSAndroid Build Coastguard Worker 				test_num, (unsigned long long)event->mask,
755*49cdfc7eSAndroid Build Coastguard Worker 				(unsigned int)event->pid, event->fd, filename,
756*49cdfc7eSAndroid Build Coastguard Worker 				event->event_len, info_id, event_fid->hdr.info_type,
757*49cdfc7eSAndroid Build Coastguard Worker 				event_fid->hdr.len, fhlen);
758*49cdfc7eSAndroid Build Coastguard Worker 		}
759*49cdfc7eSAndroid Build Coastguard Worker 
760*49cdfc7eSAndroid Build Coastguard Worker 		if (test_num < tst_count)
761*49cdfc7eSAndroid Build Coastguard Worker 			test_num++;
762*49cdfc7eSAndroid Build Coastguard Worker 
763*49cdfc7eSAndroid Build Coastguard Worker 		if (mask_match) {
764*49cdfc7eSAndroid Build Coastguard Worker 			/* In case of merged event match next expected mask */
765*49cdfc7eSAndroid Build Coastguard Worker 			event->mask &= ~expected->mask | FAN_ONDIR;
766*49cdfc7eSAndroid Build Coastguard Worker 			if (event->mask & ~FAN_ONDIR)
767*49cdfc7eSAndroid Build Coastguard Worker 				continue;
768*49cdfc7eSAndroid Build Coastguard Worker 		}
769*49cdfc7eSAndroid Build Coastguard Worker 
770*49cdfc7eSAndroid Build Coastguard Worker 		i += event->event_len;
771*49cdfc7eSAndroid Build Coastguard Worker 		if (event->fd > 0)
772*49cdfc7eSAndroid Build Coastguard Worker 			SAFE_CLOSE(event->fd);
773*49cdfc7eSAndroid Build Coastguard Worker 	}
774*49cdfc7eSAndroid Build Coastguard Worker 
775*49cdfc7eSAndroid Build Coastguard Worker 	for (; test_num < tst_count; test_num++) {
776*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "didn't get event: mask=%llx, name='%s'",
777*49cdfc7eSAndroid Build Coastguard Worker 			 event_set[test_num].mask, event_set[test_num].name);
778*49cdfc7eSAndroid Build Coastguard Worker 
779*49cdfc7eSAndroid Build Coastguard Worker 	}
780*49cdfc7eSAndroid Build Coastguard Worker }
781*49cdfc7eSAndroid Build Coastguard Worker 
setup(void)782*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
783*49cdfc7eSAndroid Build Coastguard Worker {
784*49cdfc7eSAndroid Build Coastguard Worker 	REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_DIR_FID, MOUNT_PATH);
785*49cdfc7eSAndroid Build Coastguard Worker 	fan_report_target_fid_unsupported =
786*49cdfc7eSAndroid Build Coastguard Worker 		fanotify_init_flags_supported_on_fs(FAN_REPORT_DFID_NAME_TARGET, MOUNT_PATH);
787*49cdfc7eSAndroid Build Coastguard Worker 	filesystem_mark_unsupported =
788*49cdfc7eSAndroid Build Coastguard Worker 		fanotify_flags_supported_on_fs(FAN_REPORT_FID, FAN_MARK_FILESYSTEM, FAN_OPEN,
789*49cdfc7eSAndroid Build Coastguard Worker 						MOUNT_PATH);
790*49cdfc7eSAndroid Build Coastguard Worker 	rename_events_unsupported =
791*49cdfc7eSAndroid Build Coastguard Worker 		fanotify_flags_supported_on_fs(FAN_REPORT_DFID_NAME, 0,
792*49cdfc7eSAndroid Build Coastguard Worker 					       FAN_RENAME, MOUNT_PATH);
793*49cdfc7eSAndroid Build Coastguard Worker 
794*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_MKDIR(TEMP_DIR, 0755);
795*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(dname1, "%s/%s", MOUNT_PATH, DIR_NAME1);
796*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(dname2, "%s/%s", MOUNT_PATH, DIR_NAME2);
797*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(tmpdir, "%s/%s", TEMP_DIR, DIR_NAME2);
798*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(fname1, "%s/%s", dname1, FILE_NAME1);
799*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(fname2, "%s/%s", dname1, FILE_NAME2);
800*49cdfc7eSAndroid Build Coastguard Worker }
801*49cdfc7eSAndroid Build Coastguard Worker 
cleanup(void)802*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
803*49cdfc7eSAndroid Build Coastguard Worker {
804*49cdfc7eSAndroid Build Coastguard Worker 	if (fd_notify > 0)
805*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_CLOSE(fd_notify);
806*49cdfc7eSAndroid Build Coastguard Worker }
807*49cdfc7eSAndroid Build Coastguard Worker 
808*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
809*49cdfc7eSAndroid Build Coastguard Worker 	.test = do_test,
810*49cdfc7eSAndroid Build Coastguard Worker 	.tcnt = ARRAY_SIZE(test_cases),
811*49cdfc7eSAndroid Build Coastguard Worker 	.setup = setup,
812*49cdfc7eSAndroid Build Coastguard Worker 	.cleanup = cleanup,
813*49cdfc7eSAndroid Build Coastguard Worker 	.mount_device = 1,
814*49cdfc7eSAndroid Build Coastguard Worker 	.mntpoint = MOUNT_PATH,
815*49cdfc7eSAndroid Build Coastguard Worker 	.all_filesystems = 1,
816*49cdfc7eSAndroid Build Coastguard Worker 	.needs_root = 1
817*49cdfc7eSAndroid Build Coastguard Worker };
818*49cdfc7eSAndroid Build Coastguard Worker 
819*49cdfc7eSAndroid Build Coastguard Worker #else
820*49cdfc7eSAndroid Build Coastguard Worker 	TST_TEST_TCONF("system does not have required name_to_handle_at() support");
821*49cdfc7eSAndroid Build Coastguard Worker #endif
822*49cdfc7eSAndroid Build Coastguard Worker #else
823*49cdfc7eSAndroid Build Coastguard Worker 	TST_TEST_TCONF("system doesn't have required fanotify support");
824*49cdfc7eSAndroid Build Coastguard Worker #endif
825