aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs/debug.c
diff options
context:
space:
mode:
authorArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2012-08-22 10:35:11 -0400
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2012-08-31 10:32:38 -0400
commit8089ed792832e5d3dd219da435c5a08d969662b4 (patch)
tree2d9b661683a9e687e308d90be791a61f13b8a18a /fs/ubifs/debug.c
parent4b3e58a6d6c62b5457ff876fdfc79f66fff04cd2 (diff)
UBIFS: fix power cut emulation for mtdram
The power cut emulation did not work correctly because we corrupted more than one max. I/O unit in the buffer and then wrote the entire buffer. This lead to recovery errors because UBIFS complained about corrupted free space. And this was easily reproducible on mtdram because max. write size is very small there (64 bytes), and we could easily have a 1KiB buffer, corrupt 128 bytes there, and then write the entire buffer. The fix is to corrupt max. write size bytes at most, and write only up to the last corrupted max. write size chunk, not the entire buffer. Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'fs/ubifs/debug.c')
-rw-r--r--fs/ubifs/debug.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 1aaa9f519485..5dc993fdca87 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2646,20 +2646,18 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
2646 return 1; 2646 return 1;
2647} 2647}
2648 2648
2649static void cut_data(const void *buf, unsigned int len) 2649static int corrupt_data(const struct ubifs_info *c, const void *buf,
2650 unsigned int len)
2650{ 2651{
2651 unsigned int from, to, i, ffs = chance(1, 2); 2652 unsigned int from, to, i, ffs = chance(1, 2);
2652 unsigned char *p = (void *)buf; 2653 unsigned char *p = (void *)buf;
2653 2654
2654 from = random32() % (len + 1); 2655 from = random32() % (len + 1);
2655 if (chance(1, 2)) 2656 /* Corruption may only span one max. write unit */
2656 to = random32() % (len - from + 1); 2657 to = min(len, ALIGN(from, c->max_write_size));
2657 else
2658 to = len;
2659 2658
2660 if (from < to) 2659 ubifs_warn("filled bytes %u-%u with %s", from, to - 1,
2661 ubifs_warn("filled bytes %u-%u with %s", from, to - 1, 2660 ffs ? "0xFFs" : "random data");
2662 ffs ? "0xFFs" : "random data");
2663 2661
2664 if (ffs) 2662 if (ffs)
2665 for (i = from; i < to; i++) 2663 for (i = from; i < to; i++)
@@ -2667,6 +2665,8 @@ static void cut_data(const void *buf, unsigned int len)
2667 else 2665 else
2668 for (i = from; i < to; i++) 2666 for (i = from; i < to; i++)
2669 p[i] = random32() % 0x100; 2667 p[i] = random32() % 0x100;
2668
2669 return to;
2670} 2670}
2671 2671
2672int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, 2672int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
@@ -2679,7 +2679,9 @@ int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
2679 2679
2680 failing = power_cut_emulated(c, lnum, 1); 2680 failing = power_cut_emulated(c, lnum, 1);
2681 if (failing) 2681 if (failing)
2682 cut_data(buf, len); 2682 len = corrupt_data(c, buf, len);
2683 ubifs_warn("actually write %d bytes to LEB %d:%d (the buffer was corrupted)",
2684 len, lnum, offs);
2683 err = ubi_leb_write(c->ubi, lnum, buf, offs, len); 2685 err = ubi_leb_write(c->ubi, lnum, buf, offs, len);
2684 if (err) 2686 if (err)
2685 return err; 2687 return err;