xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/fanotify/fanotify22.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) 2021 Collabora Ltd.
4*49cdfc7eSAndroid Build Coastguard Worker  *
5*49cdfc7eSAndroid Build Coastguard Worker  * Author: Gabriel Krisman Bertazi <[email protected]>
6*49cdfc7eSAndroid Build Coastguard Worker  * Based on previous work by Amir Goldstein <[email protected]>
7*49cdfc7eSAndroid Build Coastguard Worker  */
8*49cdfc7eSAndroid Build Coastguard Worker 
9*49cdfc7eSAndroid Build Coastguard Worker /*\
10*49cdfc7eSAndroid Build Coastguard Worker  * [Description]
11*49cdfc7eSAndroid Build Coastguard Worker  * Check fanotify FAN_ERROR_FS events triggered by intentionally
12*49cdfc7eSAndroid Build Coastguard Worker  * corrupted filesystems:
13*49cdfc7eSAndroid Build Coastguard Worker  *
14*49cdfc7eSAndroid Build Coastguard Worker  * - Generate a broken filesystem
15*49cdfc7eSAndroid Build Coastguard Worker  * - Start FAN_FS_ERROR monitoring group
16*49cdfc7eSAndroid Build Coastguard Worker  * - Make the file system notice the error through ordinary operations
17*49cdfc7eSAndroid Build Coastguard Worker  * - Observe the event generated
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/types.h>
25*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
26*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
27*49cdfc7eSAndroid Build Coastguard Worker #include <sys/mount.h>
28*49cdfc7eSAndroid Build Coastguard Worker #include <sys/syscall.h>
29*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
30*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.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 #ifndef EFSCORRUPTED
36*49cdfc7eSAndroid Build Coastguard Worker #define EFSCORRUPTED    EUCLEAN         /* Filesystem is corrupted */
37*49cdfc7eSAndroid Build Coastguard Worker #endif
38*49cdfc7eSAndroid Build Coastguard Worker 
39*49cdfc7eSAndroid Build Coastguard Worker #define BUF_SIZE 256
40*49cdfc7eSAndroid Build Coastguard Worker 
41*49cdfc7eSAndroid Build Coastguard Worker #define MOUNT_PATH "test_mnt"
42*49cdfc7eSAndroid Build Coastguard Worker #define BASE_DIR "internal_dir"
43*49cdfc7eSAndroid Build Coastguard Worker #define BAD_DIR BASE_DIR"/bad_dir"
44*49cdfc7eSAndroid Build Coastguard Worker #define BAD_LINK BASE_DIR"/bad_link"
45*49cdfc7eSAndroid Build Coastguard Worker 
46*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_NAME_TO_HANDLE_AT
47*49cdfc7eSAndroid Build Coastguard Worker 
48*49cdfc7eSAndroid Build Coastguard Worker static char event_buf[BUF_SIZE];
49*49cdfc7eSAndroid Build Coastguard Worker static int fd_notify;
50*49cdfc7eSAndroid Build Coastguard Worker 
51*49cdfc7eSAndroid Build Coastguard Worker /* These expected FIDs are common to multiple tests */
52*49cdfc7eSAndroid Build Coastguard Worker static struct fanotify_fid_t null_fid;
53*49cdfc7eSAndroid Build Coastguard Worker static struct fanotify_fid_t bad_file_fid;
54*49cdfc7eSAndroid Build Coastguard Worker static struct fanotify_fid_t bad_link_fid;
55*49cdfc7eSAndroid Build Coastguard Worker 
trigger_fs_abort(void)56*49cdfc7eSAndroid Build Coastguard Worker static void trigger_fs_abort(void)
57*49cdfc7eSAndroid Build Coastguard Worker {
58*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_MOUNT(tst_device->dev, MOUNT_PATH, tst_device->fs_type,
59*49cdfc7eSAndroid Build Coastguard Worker 		   MS_REMOUNT|MS_RDONLY, "abort");
60*49cdfc7eSAndroid Build Coastguard Worker }
61*49cdfc7eSAndroid Build Coastguard Worker 
do_debugfs_request(const char * dev,char * request)62*49cdfc7eSAndroid Build Coastguard Worker static void do_debugfs_request(const char *dev, char *request)
63*49cdfc7eSAndroid Build Coastguard Worker {
64*49cdfc7eSAndroid Build Coastguard Worker 	const char *const cmd[] = {"debugfs", "-w", dev, "-R", request, NULL};
65*49cdfc7eSAndroid Build Coastguard Worker 
66*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CMD(cmd, NULL, NULL);
67*49cdfc7eSAndroid Build Coastguard Worker }
68*49cdfc7eSAndroid Build Coastguard Worker 
trigger_bad_file_lookup(void)69*49cdfc7eSAndroid Build Coastguard Worker static void trigger_bad_file_lookup(void)
70*49cdfc7eSAndroid Build Coastguard Worker {
71*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
72*49cdfc7eSAndroid Build Coastguard Worker 
73*49cdfc7eSAndroid Build Coastguard Worker 	/* SAFE_OPEN cannot be used here because we expect it to fail. */
74*49cdfc7eSAndroid Build Coastguard Worker 	ret = open(MOUNT_PATH"/"BAD_DIR, O_RDONLY, 0);
75*49cdfc7eSAndroid Build Coastguard Worker 	if (ret != -1 && errno != EUCLEAN)
76*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "Unexpected lookup result(%d) of %s (%d!=%d)",
77*49cdfc7eSAndroid Build Coastguard Worker 			ret, BAD_DIR, errno, EUCLEAN);
78*49cdfc7eSAndroid Build Coastguard Worker }
79*49cdfc7eSAndroid Build Coastguard Worker 
trigger_bad_link_lookup(void)80*49cdfc7eSAndroid Build Coastguard Worker static void trigger_bad_link_lookup(void)
81*49cdfc7eSAndroid Build Coastguard Worker {
82*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
83*49cdfc7eSAndroid Build Coastguard Worker 
84*49cdfc7eSAndroid Build Coastguard Worker 	/* SAFE_OPEN cannot be used here because we expect it to fail. */
85*49cdfc7eSAndroid Build Coastguard Worker 	ret = open(MOUNT_PATH"/"BAD_LINK, O_RDONLY, 0);
86*49cdfc7eSAndroid Build Coastguard Worker 	if (ret != -1 && errno != EUCLEAN)
87*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "Unexpected open result(%d) of %s (%d!=%d)",
88*49cdfc7eSAndroid Build Coastguard Worker 			ret, BAD_LINK, errno, EUCLEAN);
89*49cdfc7eSAndroid Build Coastguard Worker }
90*49cdfc7eSAndroid Build Coastguard Worker 
91*49cdfc7eSAndroid Build Coastguard Worker 
tcase3_trigger(void)92*49cdfc7eSAndroid Build Coastguard Worker static void tcase3_trigger(void)
93*49cdfc7eSAndroid Build Coastguard Worker {
94*49cdfc7eSAndroid Build Coastguard Worker 	trigger_bad_link_lookup();
95*49cdfc7eSAndroid Build Coastguard Worker 	trigger_bad_file_lookup();
96*49cdfc7eSAndroid Build Coastguard Worker }
97*49cdfc7eSAndroid Build Coastguard Worker 
tcase4_trigger(void)98*49cdfc7eSAndroid Build Coastguard Worker static void tcase4_trigger(void)
99*49cdfc7eSAndroid Build Coastguard Worker {
100*49cdfc7eSAndroid Build Coastguard Worker 	trigger_bad_file_lookup();
101*49cdfc7eSAndroid Build Coastguard Worker 	trigger_fs_abort();
102*49cdfc7eSAndroid Build Coastguard Worker }
103*49cdfc7eSAndroid Build Coastguard Worker 
104*49cdfc7eSAndroid Build Coastguard Worker static struct test_case {
105*49cdfc7eSAndroid Build Coastguard Worker 	char *name;
106*49cdfc7eSAndroid Build Coastguard Worker 	int error;
107*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int error_count;
108*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_fid_t *fid;
109*49cdfc7eSAndroid Build Coastguard Worker 	void (*trigger_error)(void);
110*49cdfc7eSAndroid Build Coastguard Worker } testcases[] = {
111*49cdfc7eSAndroid Build Coastguard Worker 	{
112*49cdfc7eSAndroid Build Coastguard Worker 		.name = "Trigger abort",
113*49cdfc7eSAndroid Build Coastguard Worker 		.trigger_error = &trigger_fs_abort,
114*49cdfc7eSAndroid Build Coastguard Worker 		.error_count = 1,
115*49cdfc7eSAndroid Build Coastguard Worker 		.error = ESHUTDOWN,
116*49cdfc7eSAndroid Build Coastguard Worker 		.fid = &null_fid,
117*49cdfc7eSAndroid Build Coastguard Worker 	},
118*49cdfc7eSAndroid Build Coastguard Worker 	{
119*49cdfc7eSAndroid Build Coastguard Worker 		.name = "Lookup of inode with invalid mode",
120*49cdfc7eSAndroid Build Coastguard Worker 		.trigger_error = &trigger_bad_file_lookup,
121*49cdfc7eSAndroid Build Coastguard Worker 		.error_count = 1,
122*49cdfc7eSAndroid Build Coastguard Worker 		.error = EFSCORRUPTED,
123*49cdfc7eSAndroid Build Coastguard Worker 		.fid = &bad_file_fid,
124*49cdfc7eSAndroid Build Coastguard Worker 	},
125*49cdfc7eSAndroid Build Coastguard Worker 	{
126*49cdfc7eSAndroid Build Coastguard Worker 		.name = "Multiple error submission",
127*49cdfc7eSAndroid Build Coastguard Worker 		.trigger_error = &tcase3_trigger,
128*49cdfc7eSAndroid Build Coastguard Worker 		.error_count = 2,
129*49cdfc7eSAndroid Build Coastguard Worker 		.error = EFSCORRUPTED,
130*49cdfc7eSAndroid Build Coastguard Worker 		.fid = &bad_link_fid,
131*49cdfc7eSAndroid Build Coastguard Worker 	},
132*49cdfc7eSAndroid Build Coastguard Worker 	{
133*49cdfc7eSAndroid Build Coastguard Worker 		.name = "Multiple error submission 2",
134*49cdfc7eSAndroid Build Coastguard Worker 		.trigger_error = &tcase4_trigger,
135*49cdfc7eSAndroid Build Coastguard Worker 		.error_count = 2,
136*49cdfc7eSAndroid Build Coastguard Worker 		.error = EFSCORRUPTED,
137*49cdfc7eSAndroid Build Coastguard Worker 		.fid = &bad_file_fid,
138*49cdfc7eSAndroid Build Coastguard Worker 	}
139*49cdfc7eSAndroid Build Coastguard Worker };
140*49cdfc7eSAndroid Build Coastguard Worker 
check_error_event_info_fid(struct fanotify_event_info_fid * fid,const struct test_case * ex)141*49cdfc7eSAndroid Build Coastguard Worker static int check_error_event_info_fid(struct fanotify_event_info_fid *fid,
142*49cdfc7eSAndroid Build Coastguard Worker 				 const struct test_case *ex)
143*49cdfc7eSAndroid Build Coastguard Worker {
144*49cdfc7eSAndroid Build Coastguard Worker 	struct file_handle *fh = (struct file_handle *) &fid->handle;
145*49cdfc7eSAndroid Build Coastguard Worker 
146*49cdfc7eSAndroid Build Coastguard Worker 	if (memcmp(&fid->fsid, &ex->fid->fsid, sizeof(fid->fsid))) {
147*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s: Received bad FSID type (%x...!=%x...)",
148*49cdfc7eSAndroid Build Coastguard Worker 			ex->name, FSID_VAL_MEMBER(fid->fsid, 0),
149*49cdfc7eSAndroid Build Coastguard Worker 			ex->fid->fsid.val[0]);
150*49cdfc7eSAndroid Build Coastguard Worker 
151*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
152*49cdfc7eSAndroid Build Coastguard Worker 	}
153*49cdfc7eSAndroid Build Coastguard Worker 	if (fh->handle_type != ex->fid->handle.handle_type) {
154*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s: Received bad file_handle type (%d!=%d)",
155*49cdfc7eSAndroid Build Coastguard Worker 			ex->name, fh->handle_type, ex->fid->handle.handle_type);
156*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
157*49cdfc7eSAndroid Build Coastguard Worker 	}
158*49cdfc7eSAndroid Build Coastguard Worker 
159*49cdfc7eSAndroid Build Coastguard Worker 	if (fh->handle_bytes != ex->fid->handle.handle_bytes) {
160*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s: Received bad file_handle len (%d!=%d)",
161*49cdfc7eSAndroid Build Coastguard Worker 			ex->name, fh->handle_bytes, ex->fid->handle.handle_bytes);
162*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
163*49cdfc7eSAndroid Build Coastguard Worker 	}
164*49cdfc7eSAndroid Build Coastguard Worker 
165*49cdfc7eSAndroid Build Coastguard Worker 	if (memcmp(fh->f_handle, ex->fid->handle.f_handle, fh->handle_bytes)) {
166*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s: Received wrong handle. "
167*49cdfc7eSAndroid Build Coastguard Worker 			"Expected (%x...) got (%x...) ", ex->name,
168*49cdfc7eSAndroid Build Coastguard Worker 			*(int *)ex->fid->handle.f_handle, *(int *)fh->f_handle);
169*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
170*49cdfc7eSAndroid Build Coastguard Worker 	}
171*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
172*49cdfc7eSAndroid Build Coastguard Worker }
173*49cdfc7eSAndroid Build Coastguard Worker 
check_error_event_info_error(struct fanotify_event_info_error * info_error,const struct test_case * ex)174*49cdfc7eSAndroid Build Coastguard Worker static int check_error_event_info_error(struct fanotify_event_info_error *info_error,
175*49cdfc7eSAndroid Build Coastguard Worker 				 const struct test_case *ex)
176*49cdfc7eSAndroid Build Coastguard Worker {
177*49cdfc7eSAndroid Build Coastguard Worker 	int fail = 0;
178*49cdfc7eSAndroid Build Coastguard Worker 
179*49cdfc7eSAndroid Build Coastguard Worker 	if (info_error->error_count != ex->error_count) {
180*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s: Unexpected error_count (%d!=%d)",
181*49cdfc7eSAndroid Build Coastguard Worker 			ex->name, info_error->error_count, ex->error_count);
182*49cdfc7eSAndroid Build Coastguard Worker 		fail++;
183*49cdfc7eSAndroid Build Coastguard Worker 	}
184*49cdfc7eSAndroid Build Coastguard Worker 
185*49cdfc7eSAndroid Build Coastguard Worker 	if (info_error->error != ex->error) {
186*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s: Unexpected error code value (%d!=%d)",
187*49cdfc7eSAndroid Build Coastguard Worker 			ex->name, info_error->error, ex->error);
188*49cdfc7eSAndroid Build Coastguard Worker 		fail++;
189*49cdfc7eSAndroid Build Coastguard Worker 	}
190*49cdfc7eSAndroid Build Coastguard Worker 
191*49cdfc7eSAndroid Build Coastguard Worker 	return fail;
192*49cdfc7eSAndroid Build Coastguard Worker }
193*49cdfc7eSAndroid Build Coastguard Worker 
check_error_event_metadata(struct fanotify_event_metadata * event)194*49cdfc7eSAndroid Build Coastguard Worker static int check_error_event_metadata(struct fanotify_event_metadata *event)
195*49cdfc7eSAndroid Build Coastguard Worker {
196*49cdfc7eSAndroid Build Coastguard Worker 	int fail = 0;
197*49cdfc7eSAndroid Build Coastguard Worker 
198*49cdfc7eSAndroid Build Coastguard Worker 	if (event->mask != FAN_FS_ERROR) {
199*49cdfc7eSAndroid Build Coastguard Worker 		fail++;
200*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "got unexpected event %llx",
201*49cdfc7eSAndroid Build Coastguard Worker 			(unsigned long long)event->mask);
202*49cdfc7eSAndroid Build Coastguard Worker 	}
203*49cdfc7eSAndroid Build Coastguard Worker 
204*49cdfc7eSAndroid Build Coastguard Worker 	if (event->fd != FAN_NOFD) {
205*49cdfc7eSAndroid Build Coastguard Worker 		fail++;
206*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "Weird FAN_FD %llx",
207*49cdfc7eSAndroid Build Coastguard Worker 			(unsigned long long)event->mask);
208*49cdfc7eSAndroid Build Coastguard Worker 	}
209*49cdfc7eSAndroid Build Coastguard Worker 	return fail;
210*49cdfc7eSAndroid Build Coastguard Worker }
211*49cdfc7eSAndroid Build Coastguard Worker 
check_event(char * buf,size_t len,const struct test_case * ex)212*49cdfc7eSAndroid Build Coastguard Worker static void check_event(char *buf, size_t len, const struct test_case *ex)
213*49cdfc7eSAndroid Build Coastguard Worker {
214*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_event_metadata *event =
215*49cdfc7eSAndroid Build Coastguard Worker 		(struct fanotify_event_metadata *) buf;
216*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_event_info_error *info_error;
217*49cdfc7eSAndroid Build Coastguard Worker 	struct fanotify_event_info_fid *info_fid;
218*49cdfc7eSAndroid Build Coastguard Worker 	int fail = 0;
219*49cdfc7eSAndroid Build Coastguard Worker 
220*49cdfc7eSAndroid Build Coastguard Worker 	if (len < FAN_EVENT_METADATA_LEN) {
221*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "No event metadata found");
222*49cdfc7eSAndroid Build Coastguard Worker 		return;
223*49cdfc7eSAndroid Build Coastguard Worker 	}
224*49cdfc7eSAndroid Build Coastguard Worker 
225*49cdfc7eSAndroid Build Coastguard Worker 	if (check_error_event_metadata(event))
226*49cdfc7eSAndroid Build Coastguard Worker 		return;
227*49cdfc7eSAndroid Build Coastguard Worker 
228*49cdfc7eSAndroid Build Coastguard Worker 	info_error = get_event_info_error(event);
229*49cdfc7eSAndroid Build Coastguard Worker 	if (info_error)
230*49cdfc7eSAndroid Build Coastguard Worker 		fail += check_error_event_info_error(info_error, ex);
231*49cdfc7eSAndroid Build Coastguard Worker 	else {
232*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "Generic error record not found");
233*49cdfc7eSAndroid Build Coastguard Worker 		fail++;
234*49cdfc7eSAndroid Build Coastguard Worker 	}
235*49cdfc7eSAndroid Build Coastguard Worker 
236*49cdfc7eSAndroid Build Coastguard Worker 	info_fid = get_event_info_fid(event);
237*49cdfc7eSAndroid Build Coastguard Worker 	if (info_fid)
238*49cdfc7eSAndroid Build Coastguard Worker 		fail += check_error_event_info_fid(info_fid, ex);
239*49cdfc7eSAndroid Build Coastguard Worker 	else {
240*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "FID record not found");
241*49cdfc7eSAndroid Build Coastguard Worker 		fail++;
242*49cdfc7eSAndroid Build Coastguard Worker 	}
243*49cdfc7eSAndroid Build Coastguard Worker 
244*49cdfc7eSAndroid Build Coastguard Worker 	if (!fail)
245*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TPASS, "Successfully received: %s", ex->name);
246*49cdfc7eSAndroid Build Coastguard Worker }
247*49cdfc7eSAndroid Build Coastguard Worker 
do_test(unsigned int i)248*49cdfc7eSAndroid Build Coastguard Worker static void do_test(unsigned int i)
249*49cdfc7eSAndroid Build Coastguard Worker {
250*49cdfc7eSAndroid Build Coastguard Worker 	const struct test_case *tcase = &testcases[i];
251*49cdfc7eSAndroid Build Coastguard Worker 	size_t read_len;
252*49cdfc7eSAndroid Build Coastguard Worker 
253*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_ADD|FAN_MARK_FILESYSTEM,
254*49cdfc7eSAndroid Build Coastguard Worker 			   FAN_FS_ERROR, AT_FDCWD, MOUNT_PATH);
255*49cdfc7eSAndroid Build Coastguard Worker 
256*49cdfc7eSAndroid Build Coastguard Worker 	tcase->trigger_error();
257*49cdfc7eSAndroid Build Coastguard Worker 
258*49cdfc7eSAndroid Build Coastguard Worker 	read_len = SAFE_READ(0, fd_notify, event_buf, BUF_SIZE);
259*49cdfc7eSAndroid Build Coastguard Worker 
260*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_REMOVE|FAN_MARK_FILESYSTEM,
261*49cdfc7eSAndroid Build Coastguard Worker 			   FAN_FS_ERROR, AT_FDCWD, MOUNT_PATH);
262*49cdfc7eSAndroid Build Coastguard Worker 
263*49cdfc7eSAndroid Build Coastguard Worker 	check_event(event_buf, read_len, tcase);
264*49cdfc7eSAndroid Build Coastguard Worker 	/* Unmount and mount the filesystem to get it out of the error state */
265*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_UMOUNT(MOUNT_PATH);
266*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_MOUNT(tst_device->dev, MOUNT_PATH, tst_device->fs_type, 0, NULL);
267*49cdfc7eSAndroid Build Coastguard Worker }
268*49cdfc7eSAndroid Build Coastguard Worker 
pre_corrupt_fs(void)269*49cdfc7eSAndroid Build Coastguard Worker static void pre_corrupt_fs(void)
270*49cdfc7eSAndroid Build Coastguard Worker {
271*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_MKDIR(MOUNT_PATH"/"BASE_DIR, 0777);
272*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_MKDIR(MOUNT_PATH"/"BAD_DIR, 0777);
273*49cdfc7eSAndroid Build Coastguard Worker 
274*49cdfc7eSAndroid Build Coastguard Worker 	fanotify_save_fid(MOUNT_PATH"/"BAD_DIR, &bad_file_fid);
275*49cdfc7eSAndroid Build Coastguard Worker 	fanotify_save_fid(MOUNT_PATH"/"BASE_DIR, &bad_link_fid);
276*49cdfc7eSAndroid Build Coastguard Worker 
277*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_UMOUNT(MOUNT_PATH);
278*49cdfc7eSAndroid Build Coastguard Worker 	do_debugfs_request(tst_device->dev, "sif " BAD_DIR " mode 0xff");
279*49cdfc7eSAndroid Build Coastguard Worker 	do_debugfs_request(tst_device->dev, "ln <1> " BAD_LINK);
280*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_MOUNT(tst_device->dev, MOUNT_PATH, tst_device->fs_type, 0, NULL);
281*49cdfc7eSAndroid Build Coastguard Worker }
282*49cdfc7eSAndroid Build Coastguard Worker 
init_null_fid(void)283*49cdfc7eSAndroid Build Coastguard Worker static void init_null_fid(void)
284*49cdfc7eSAndroid Build Coastguard Worker {
285*49cdfc7eSAndroid Build Coastguard Worker 	/* Use fanotify_save_fid to fill the fsid and overwrite the
286*49cdfc7eSAndroid Build Coastguard Worker 	 * file_handler to create a null_fid
287*49cdfc7eSAndroid Build Coastguard Worker 	 */
288*49cdfc7eSAndroid Build Coastguard Worker 	fanotify_save_fid(MOUNT_PATH, &null_fid);
289*49cdfc7eSAndroid Build Coastguard Worker 
290*49cdfc7eSAndroid Build Coastguard Worker 	null_fid.handle.handle_type = FILEID_INVALID;
291*49cdfc7eSAndroid Build Coastguard Worker 	null_fid.handle.handle_bytes = 0;
292*49cdfc7eSAndroid Build Coastguard Worker }
293*49cdfc7eSAndroid Build Coastguard Worker 
setup(void)294*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
295*49cdfc7eSAndroid Build Coastguard Worker {
296*49cdfc7eSAndroid Build Coastguard Worker 	REQUIRE_FANOTIFY_EVENTS_SUPPORTED_ON_FS(FAN_CLASS_NOTIF|FAN_REPORT_FID,
297*49cdfc7eSAndroid Build Coastguard Worker 						FAN_MARK_FILESYSTEM,
298*49cdfc7eSAndroid Build Coastguard Worker 						FAN_FS_ERROR, ".");
299*49cdfc7eSAndroid Build Coastguard Worker 	pre_corrupt_fs();
300*49cdfc7eSAndroid Build Coastguard Worker 
301*49cdfc7eSAndroid Build Coastguard Worker 	fd_notify = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF|FAN_REPORT_FID,
302*49cdfc7eSAndroid Build Coastguard Worker 				       O_RDONLY);
303*49cdfc7eSAndroid Build Coastguard Worker 
304*49cdfc7eSAndroid Build Coastguard Worker 	init_null_fid();
305*49cdfc7eSAndroid Build Coastguard Worker }
306*49cdfc7eSAndroid Build Coastguard Worker 
cleanup(void)307*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
308*49cdfc7eSAndroid Build Coastguard Worker {
309*49cdfc7eSAndroid Build Coastguard Worker 	if (fd_notify > 0)
310*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_CLOSE(fd_notify);
311*49cdfc7eSAndroid Build Coastguard Worker }
312*49cdfc7eSAndroid Build Coastguard Worker 
313*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
314*49cdfc7eSAndroid Build Coastguard Worker 	.test = do_test,
315*49cdfc7eSAndroid Build Coastguard Worker 	.tcnt = ARRAY_SIZE(testcases),
316*49cdfc7eSAndroid Build Coastguard Worker 	.setup = setup,
317*49cdfc7eSAndroid Build Coastguard Worker 	.cleanup = cleanup,
318*49cdfc7eSAndroid Build Coastguard Worker 	.mount_device = 1,
319*49cdfc7eSAndroid Build Coastguard Worker 	.mntpoint = MOUNT_PATH,
320*49cdfc7eSAndroid Build Coastguard Worker 	.needs_root = 1,
321*49cdfc7eSAndroid Build Coastguard Worker 	.dev_fs_type = "ext4",
322*49cdfc7eSAndroid Build Coastguard Worker 	.tags = (const struct tst_tag[]) {
323*49cdfc7eSAndroid Build Coastguard Worker 		{"linux-git", "124e7c61deb2"},
324*49cdfc7eSAndroid Build Coastguard Worker 		{}
325*49cdfc7eSAndroid Build Coastguard Worker 	},
326*49cdfc7eSAndroid Build Coastguard Worker 	.needs_cmds = (const char *[]) {
327*49cdfc7eSAndroid Build Coastguard Worker 		"debugfs",
328*49cdfc7eSAndroid Build Coastguard Worker 		NULL
329*49cdfc7eSAndroid Build Coastguard Worker 	}
330*49cdfc7eSAndroid Build Coastguard Worker };
331*49cdfc7eSAndroid Build Coastguard Worker 
332*49cdfc7eSAndroid Build Coastguard Worker #else
333*49cdfc7eSAndroid Build Coastguard Worker 	TST_TEST_TCONF("system does not have required name_to_handle_at() support");
334*49cdfc7eSAndroid Build Coastguard Worker #endif
335*49cdfc7eSAndroid Build Coastguard Worker #else
336*49cdfc7eSAndroid Build Coastguard Worker 	TST_TEST_TCONF("system doesn't have required fanotify support");
337*49cdfc7eSAndroid Build Coastguard Worker #endif
338