10
10
#include <linux/uaccess.h>
11
11
#include <linux/module.h>
12
12
#include <linux/seq_file.h>
13
+ #include <linux/fault-inject.h>
14
+
15
+ #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
16
+ static DECLARE_FAULT_ATTR (fault_eccerr_attr );
17
+ static DECLARE_FAULT_ATTR (fault_bitflips_attr );
18
+ static DECLARE_FAULT_ATTR (fault_read_failure_attr );
19
+ static DECLARE_FAULT_ATTR (fault_write_failure_attr );
20
+ static DECLARE_FAULT_ATTR (fault_erase_failure_attr );
21
+ static DECLARE_FAULT_ATTR (fault_power_cut_attr );
22
+ static DECLARE_FAULT_ATTR (fault_io_ff_attr );
23
+ static DECLARE_FAULT_ATTR (fault_io_ff_bitflips_attr );
24
+ static DECLARE_FAULT_ATTR (fault_bad_hdr_attr );
25
+ static DECLARE_FAULT_ATTR (fault_bad_hdr_ebadmsg_attr );
26
+
27
+ #define FAIL_ACTION (name , fault_attr ) \
28
+ bool should_fail_##name(void) \
29
+ { \
30
+ return should_fail(&fault_attr, 1); \
31
+ }
13
32
33
+ FAIL_ACTION (eccerr , fault_eccerr_attr )
34
+ FAIL_ACTION (bitflips , fault_bitflips_attr )
35
+ FAIL_ACTION (read_failure , fault_read_failure_attr )
36
+ FAIL_ACTION (write_failure , fault_write_failure_attr )
37
+ FAIL_ACTION (erase_failure , fault_erase_failure_attr )
38
+ FAIL_ACTION (power_cut , fault_power_cut_attr )
39
+ FAIL_ACTION (io_ff , fault_io_ff_attr )
40
+ FAIL_ACTION (io_ff_bitflips , fault_io_ff_bitflips_attr )
41
+ FAIL_ACTION (bad_hdr , fault_bad_hdr_attr )
42
+ FAIL_ACTION (bad_hdr_ebadmsg , fault_bad_hdr_ebadmsg_attr )
43
+ #endif
14
44
15
45
/**
16
46
* ubi_dump_flash - dump a region of flash.
@@ -212,6 +242,52 @@ void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req)
212
242
*/
213
243
static struct dentry * dfs_rootdir ;
214
244
245
+ #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
246
+ static void dfs_create_fault_entry (struct dentry * parent )
247
+ {
248
+ struct dentry * dir ;
249
+
250
+ dir = debugfs_create_dir ("fault_inject" , parent );
251
+ if (IS_ERR_OR_NULL (dir )) {
252
+ int err = dir ? PTR_ERR (dir ) : - ENODEV ;
253
+
254
+ pr_warn ("UBI error: cannot create \"fault_inject\" debugfs directory, error %d\n" ,
255
+ err );
256
+ return ;
257
+ }
258
+
259
+ fault_create_debugfs_attr ("emulate_eccerr" , dir ,
260
+ & fault_eccerr_attr );
261
+
262
+ fault_create_debugfs_attr ("emulate_read_failure" , dir ,
263
+ & fault_read_failure_attr );
264
+
265
+ fault_create_debugfs_attr ("emulate_bitflips" , dir ,
266
+ & fault_bitflips_attr );
267
+
268
+ fault_create_debugfs_attr ("emulate_write_failure" , dir ,
269
+ & fault_write_failure_attr );
270
+
271
+ fault_create_debugfs_attr ("emulate_erase_failure" , dir ,
272
+ & fault_erase_failure_attr );
273
+
274
+ fault_create_debugfs_attr ("emulate_power_cut" , dir ,
275
+ & fault_power_cut_attr );
276
+
277
+ fault_create_debugfs_attr ("emulate_io_ff" , dir ,
278
+ & fault_io_ff_attr );
279
+
280
+ fault_create_debugfs_attr ("emulate_io_ff_bitflips" , dir ,
281
+ & fault_io_ff_bitflips_attr );
282
+
283
+ fault_create_debugfs_attr ("emulate_bad_hdr" , dir ,
284
+ & fault_bad_hdr_attr );
285
+
286
+ fault_create_debugfs_attr ("emulate_bad_hdr_ebadmsg" , dir ,
287
+ & fault_bad_hdr_ebadmsg_attr );
288
+ }
289
+ #endif
290
+
215
291
/**
216
292
* ubi_debugfs_init - create UBI debugfs directory.
217
293
*
@@ -232,6 +308,10 @@ int ubi_debugfs_init(void)
232
308
return err ;
233
309
}
234
310
311
+ #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
312
+ dfs_create_fault_entry (dfs_rootdir );
313
+ #endif
314
+
235
315
return 0 ;
236
316
}
237
317
@@ -252,7 +332,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
252
332
struct dentry * dent = file -> f_path .dentry ;
253
333
struct ubi_device * ubi ;
254
334
struct ubi_debug_info * d ;
255
- char buf [8 ];
335
+ char buf [16 ];
256
336
int val ;
257
337
258
338
ubi = ubi_get_device (ubi_num );
@@ -272,7 +352,12 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
272
352
val = d -> emulate_bitflips ;
273
353
else if (dent == d -> dfs_emulate_io_failures )
274
354
val = d -> emulate_io_failures ;
275
- else if (dent == d -> dfs_emulate_power_cut ) {
355
+ else if (dent == d -> dfs_emulate_failures ) {
356
+ snprintf (buf , sizeof (buf ), "0x%04x\n" , d -> emulate_failures );
357
+ count = simple_read_from_buffer (user_buf , count , ppos ,
358
+ buf , strlen (buf ));
359
+ goto out ;
360
+ } else if (dent == d -> dfs_emulate_power_cut ) {
276
361
snprintf (buf , sizeof (buf ), "%u\n" , d -> emulate_power_cut );
277
362
count = simple_read_from_buffer (user_buf , count , ppos ,
278
363
buf , strlen (buf ));
@@ -287,8 +372,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
287
372
count = simple_read_from_buffer (user_buf , count , ppos ,
288
373
buf , strlen (buf ));
289
374
goto out ;
290
- }
291
- else {
375
+ } else {
292
376
count = - EINVAL ;
293
377
goto out ;
294
378
}
@@ -316,7 +400,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
316
400
struct ubi_device * ubi ;
317
401
struct ubi_debug_info * d ;
318
402
size_t buf_size ;
319
- char buf [8 ] = {0 };
403
+ char buf [16 ] = {0 };
320
404
int val ;
321
405
322
406
ubi = ubi_get_device (ubi_num );
@@ -330,7 +414,11 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
330
414
goto out ;
331
415
}
332
416
333
- if (dent == d -> dfs_power_cut_min ) {
417
+ if (dent == d -> dfs_emulate_failures ) {
418
+ if (kstrtouint (buf , 0 , & d -> emulate_failures ) != 0 )
419
+ count = - EINVAL ;
420
+ goto out ;
421
+ } else if (dent == d -> dfs_power_cut_min ) {
334
422
if (kstrtouint (buf , 0 , & d -> power_cut_min ) != 0 )
335
423
count = - EINVAL ;
336
424
goto out ;
@@ -559,6 +647,12 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
559
647
debugfs_create_file ("detailed_erase_block_info" , S_IRUSR , d -> dfs_dir ,
560
648
(void * )ubi_num , & eraseblk_count_fops );
561
649
650
+ #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
651
+ d -> dfs_emulate_failures = debugfs_create_file ("emulate_failures" ,
652
+ mode , d -> dfs_dir ,
653
+ (void * )ubi_num ,
654
+ & dfs_fops );
655
+ #endif
562
656
return 0 ;
563
657
}
564
658
@@ -600,7 +694,5 @@ int ubi_dbg_power_cut(struct ubi_device *ubi, int caller)
600
694
if (ubi -> dbg .power_cut_counter )
601
695
return 0 ;
602
696
603
- ubi_msg (ubi , "XXXXXXXXXXXXXXX emulating a power cut XXXXXXXXXXXXXXXX" );
604
- ubi_ro_mode (ubi );
605
697
return 1 ;
606
698
}
0 commit comments