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