aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/debug.c105
-rw-r--r--fs/ubifs/debug.h31
-rw-r--r--fs/ubifs/io.c8
3 files changed, 39 insertions, 105 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 3a7344124f30..1e880cedefa4 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2539,16 +2539,7 @@ error_dump:
2539 2539
2540#define chance(n, d) (simple_rand() <= (n) * 32768LL / (d)) 2540#define chance(n, d) (simple_rand() <= (n) * 32768LL / (d))
2541 2541
2542struct failure_mode_info {
2543 struct list_head list;
2544 struct ubifs_info *c;
2545};
2546
2547static LIST_HEAD(fmi_list);
2548static DEFINE_SPINLOCK(fmi_lock);
2549
2550static unsigned int next; 2542static unsigned int next;
2551
2552static int simple_rand(void) 2543static int simple_rand(void)
2553{ 2544{
2554 if (next == 0) 2545 if (next == 0)
@@ -2557,69 +2548,15 @@ static int simple_rand(void)
2557 return (next >> 16) & 32767; 2548 return (next >> 16) & 32767;
2558} 2549}
2559 2550
2560static void failure_mode_init(struct ubifs_info *c) 2551static int do_fail(struct ubifs_info *c, int lnum, int write)
2561{
2562 struct failure_mode_info *fmi;
2563
2564 fmi = kmalloc(sizeof(struct failure_mode_info), GFP_NOFS);
2565 if (!fmi) {
2566 ubifs_err("Failed to register failure mode - no memory");
2567 return;
2568 }
2569 fmi->c = c;
2570 spin_lock(&fmi_lock);
2571 list_add_tail(&fmi->list, &fmi_list);
2572 spin_unlock(&fmi_lock);
2573}
2574
2575static void failure_mode_exit(struct ubifs_info *c)
2576{
2577 struct failure_mode_info *fmi, *tmp;
2578
2579 spin_lock(&fmi_lock);
2580 list_for_each_entry_safe(fmi, tmp, &fmi_list, list)
2581 if (fmi->c == c) {
2582 list_del(&fmi->list);
2583 kfree(fmi);
2584 }
2585 spin_unlock(&fmi_lock);
2586}
2587
2588static struct ubifs_info *dbg_find_info(struct ubi_volume_desc *desc)
2589{ 2552{
2590 struct failure_mode_info *fmi; 2553 struct ubifs_debug_info *d = c->dbg;
2591
2592 spin_lock(&fmi_lock);
2593 list_for_each_entry(fmi, &fmi_list, list)
2594 if (fmi->c->ubi == desc) {
2595 struct ubifs_info *c = fmi->c;
2596
2597 spin_unlock(&fmi_lock);
2598 return c;
2599 }
2600 spin_unlock(&fmi_lock);
2601 return NULL;
2602}
2603
2604static int in_failure_mode(struct ubi_volume_desc *desc)
2605{
2606 struct ubifs_info *c = dbg_find_info(desc);
2607 2554
2608 if (c && dbg_is_tst_rcvry(c)) 2555 ubifs_assert(dbg_is_tst_rcvry(c));
2609 return c->dbg->failure_mode;
2610 return 0;
2611}
2612 2556
2613static int do_fail(struct ubi_volume_desc *desc, int lnum, int write)
2614{
2615 struct ubifs_info *c = dbg_find_info(desc);
2616 struct ubifs_debug_info *d;
2617
2618 if (!c || !dbg_is_tst_rcvry(c))
2619 return 0;
2620 d = c->dbg;
2621 if (d->failure_mode) 2557 if (d->failure_mode)
2622 return 1; 2558 return 1;
2559
2623 if (!d->fail_cnt) { 2560 if (!d->fail_cnt) {
2624 /* First call - decide delay to failure */ 2561 /* First call - decide delay to failure */
2625 if (chance(1, 2)) { 2562 if (chance(1, 2)) {
@@ -2716,17 +2653,17 @@ static void cut_data(const void *buf, int len)
2716 p[i] = 0xff; 2653 p[i] = 0xff;
2717} 2654}
2718 2655
2719int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, 2656int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
2720 int offs, int len, int dtype) 2657 int offs, int len, int dtype)
2721{ 2658{
2722 int err, failing; 2659 int err, failing;
2723 2660
2724 if (in_failure_mode(desc)) 2661 if (c->dbg->failure_mode)
2725 return -EROFS; 2662 return -EROFS;
2726 failing = do_fail(desc, lnum, 1); 2663 failing = do_fail(c, lnum, 1);
2727 if (failing) 2664 if (failing)
2728 cut_data(buf, len); 2665 cut_data(buf, len);
2729 err = ubi_leb_write(desc, lnum, buf, offs, len, dtype); 2666 err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
2730 if (err) 2667 if (err)
2731 return err; 2668 return err;
2732 if (failing) 2669 if (failing)
@@ -2734,45 +2671,45 @@ int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
2734 return 0; 2671 return 0;
2735} 2672}
2736 2673
2737int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, 2674int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf,
2738 int len, int dtype) 2675 int len, int dtype)
2739{ 2676{
2740 int err; 2677 int err;
2741 2678
2742 if (do_fail(desc, lnum, 1)) 2679 if (do_fail(c, lnum, 1))
2743 return -EROFS; 2680 return -EROFS;
2744 err = ubi_leb_change(desc, lnum, buf, len, dtype); 2681 err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
2745 if (err) 2682 if (err)
2746 return err; 2683 return err;
2747 if (do_fail(desc, lnum, 1)) 2684 if (do_fail(c, lnum, 1))
2748 return -EROFS; 2685 return -EROFS;
2749 return 0; 2686 return 0;
2750} 2687}
2751 2688
2752int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum) 2689int dbg_leb_unmap(struct ubifs_info *c, int lnum)
2753{ 2690{
2754 int err; 2691 int err;
2755 2692
2756 if (do_fail(desc, lnum, 0)) 2693 if (do_fail(c, lnum, 0))
2757 return -EROFS; 2694 return -EROFS;
2758 err = ubi_leb_unmap(desc, lnum); 2695 err = ubi_leb_unmap(c->ubi, lnum);
2759 if (err) 2696 if (err)
2760 return err; 2697 return err;
2761 if (do_fail(desc, lnum, 0)) 2698 if (do_fail(c, lnum, 0))
2762 return -EROFS; 2699 return -EROFS;
2763 return 0; 2700 return 0;
2764} 2701}
2765 2702
2766int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype) 2703int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype)
2767{ 2704{
2768 int err; 2705 int err;
2769 2706
2770 if (do_fail(desc, lnum, 0)) 2707 if (do_fail(c, lnum, 0))
2771 return -EROFS; 2708 return -EROFS;
2772 err = ubi_leb_map(desc, lnum, dtype); 2709 err = ubi_leb_map(c->ubi, lnum, dtype);
2773 if (err) 2710 if (err)
2774 return err; 2711 return err;
2775 if (do_fail(desc, lnum, 0)) 2712 if (do_fail(c, lnum, 0))
2776 return -EROFS; 2713 return -EROFS;
2777 return 0; 2714 return 0;
2778} 2715}
@@ -3210,7 +3147,6 @@ int ubifs_debugging_init(struct ubifs_info *c)
3210 if (!c->dbg) 3147 if (!c->dbg)
3211 return -ENOMEM; 3148 return -ENOMEM;
3212 3149
3213 failure_mode_init(c);
3214 return 0; 3150 return 0;
3215} 3151}
3216 3152
@@ -3220,7 +3156,6 @@ int ubifs_debugging_init(struct ubifs_info *c)
3220 */ 3156 */
3221void ubifs_debugging_exit(struct ubifs_info *c) 3157void ubifs_debugging_exit(struct ubifs_info *c)
3222{ 3158{
3223 failure_mode_exit(c);
3224 kfree(c->dbg); 3159 kfree(c->dbg);
3225} 3160}
3226 3161
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index b5bc09deeb32..0ab3757ef0e3 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -305,12 +305,12 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
305int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head); 305int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head);
306int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head); 306int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head);
307 307
308int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, 308int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
309 int offs, int len, int dtype); 309 int len, int dtype);
310int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, 310int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
311 int len, int dtype); 311 int dtype);
312int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum); 312int dbg_leb_unmap(struct ubifs_info *c, int lnum);
313int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype); 313int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype);
314 314
315/* Debugfs-related stuff */ 315/* Debugfs-related stuff */
316int dbg_debugfs_init(void); 316int dbg_debugfs_init(void);
@@ -442,16 +442,15 @@ static inline int
442dbg_check_nondata_nodes_order(struct ubifs_info *c, 442dbg_check_nondata_nodes_order(struct ubifs_info *c,
443 struct list_head *head) { return 0; } 443 struct list_head *head) { return 0; }
444 444
445static inline int dbg_leb_write(struct ubi_volume_desc *desc, 445static inline int dbg_leb_write(struct ubifs_info *c, int lnum,
446 int lnum, const void *buf, 446 const void *buf, int offset,
447 int offset, int len, int dtype) { return 0; } 447 int len, int dtype) { return 0; }
448static inline int dbg_leb_change(struct ubi_volume_desc *desc, 448static inline int dbg_leb_change(struct ubifs_info *c, int lnum,
449 int lnum, const void *buf, 449 const void *buf, int len,
450 int len, int dtype) { return 0; } 450 int dtype) { return 0; }
451static inline int dbg_leb_unmap(struct ubi_volume_desc *desc, 451static inline int dbg_leb_unmap(struct ubifs_info *c, int lnum) { return 0; }
452 int lnum) { return 0; } 452static inline int dbg_leb_map(struct ubifs_info *c, int lnum,
453static inline int dbg_leb_map(struct ubi_volume_desc *desc, 453 int dtype) { return 0; }
454 int lnum, int dtype) { return 0; }
455 454
456static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; } 455static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; }
457static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; } 456static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; }
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index a0c5fb4b6fa8..9228950a658f 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -125,7 +125,7 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
125 if (!dbg_is_tst_rcvry(c)) 125 if (!dbg_is_tst_rcvry(c))
126 err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype); 126 err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
127 else 127 else
128 err = dbg_leb_write(c->ubi, lnum, buf, offs, len, dtype); 128 err = dbg_leb_write(c, lnum, buf, offs, len, dtype);
129 if (err) { 129 if (err) {
130 ubifs_err("writing %d bytes to LEB %d:%d failed, error %d", 130 ubifs_err("writing %d bytes to LEB %d:%d failed, error %d",
131 len, lnum, offs, err); 131 len, lnum, offs, err);
@@ -146,7 +146,7 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
146 if (!dbg_is_tst_rcvry(c)) 146 if (!dbg_is_tst_rcvry(c))
147 err = ubi_leb_change(c->ubi, lnum, buf, len, dtype); 147 err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
148 else 148 else
149 err = dbg_leb_change(c->ubi, lnum, buf, len, dtype); 149 err = dbg_leb_change(c, lnum, buf, len, dtype);
150 if (err) { 150 if (err) {
151 ubifs_err("changing %d bytes in LEB %d failed, error %d", 151 ubifs_err("changing %d bytes in LEB %d failed, error %d",
152 len, lnum, err); 152 len, lnum, err);
@@ -166,7 +166,7 @@ int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
166 if (!dbg_is_tst_rcvry(c)) 166 if (!dbg_is_tst_rcvry(c))
167 err = ubi_leb_unmap(c->ubi, lnum); 167 err = ubi_leb_unmap(c->ubi, lnum);
168 else 168 else
169 err = dbg_leb_unmap(c->ubi, lnum); 169 err = dbg_leb_unmap(c, lnum);
170 if (err) { 170 if (err) {
171 ubifs_err("unmap LEB %d failed, error %d", lnum, err); 171 ubifs_err("unmap LEB %d failed, error %d", lnum, err);
172 ubifs_ro_mode(c, err); 172 ubifs_ro_mode(c, err);
@@ -185,7 +185,7 @@ int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype)
185 if (!dbg_is_tst_rcvry(c)) 185 if (!dbg_is_tst_rcvry(c))
186 err = ubi_leb_map(c->ubi, lnum, dtype); 186 err = ubi_leb_map(c->ubi, lnum, dtype);
187 else 187 else
188 err = dbg_leb_map(c->ubi, lnum, dtype); 188 err = dbg_leb_map(c, lnum, dtype);
189 if (err) { 189 if (err) {
190 ubifs_err("mapping LEB %d failed, error %d", lnum, err); 190 ubifs_err("mapping LEB %d failed, error %d", lnum, err);
191 ubifs_ro_mode(c, err); 191 ubifs_ro_mode(c, err);