summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2012-08-22 17:35:11 +0300
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2012-08-31 17:32:38 +0300
commit8089ed792832e5d3dd219da435c5a08d969662b4 (patch)
tree2d9b661683a9e687e308d90be791a61f13b8a18a
parent4b3e58a6d6c62b5457ff876fdfc79f66fff04cd2 (diff)
downloadop-kernel-dev-8089ed792832e5d3dd219da435c5a08d969662b4.zip
op-kernel-dev-8089ed792832e5d3dd219da435c5a08d969662b4.tar.gz
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>
-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 1aaa9f5..5dc993f 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)
return 1;
}
-static void cut_data(const void *buf, unsigned int len)
+static int corrupt_data(const struct ubifs_info *c, const void *buf,
+ unsigned int len)
{
unsigned int from, to, i, ffs = chance(1, 2);
unsigned char *p = (void *)buf;
from = random32() % (len + 1);
- if (chance(1, 2))
- to = random32() % (len - from + 1);
- else
- to = len;
+ /* Corruption may only span one max. write unit */
+ to = min(len, ALIGN(from, c->max_write_size));
- if (from < to)
- ubifs_warn("filled bytes %u-%u with %s", from, to - 1,
- ffs ? "0xFFs" : "random data");
+ ubifs_warn("filled bytes %u-%u with %s", from, to - 1,
+ ffs ? "0xFFs" : "random data");
if (ffs)
for (i = from; i < to; i++)
@@ -2667,6 +2665,8 @@ static void cut_data(const void *buf, unsigned int len)
else
for (i = from; i < to; i++)
p[i] = random32() % 0x100;
+
+ return to;
}
int 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,
failing = power_cut_emulated(c, lnum, 1);
if (failing)
- cut_data(buf, len);
+ len = corrupt_data(c, buf, len);
+ ubifs_warn("actually write %d bytes to LEB %d:%d (the buffer was corrupted)",
+ len, lnum, offs);
err = ubi_leb_write(c->ubi, lnum, buf, offs, len);
if (err)
return err;
OpenPOWER on IntegriCloud