Skip to content

Commit

Permalink
UBIFS: fix power cut emulation for mtdram
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Artem Bityutskiy committed Aug 31, 2012
1 parent 4b3e58a commit 8089ed7
Showing 1 changed file with 11 additions and 9 deletions.
20 changes: 11 additions & 9 deletions fs/ubifs/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -2646,27 +2646,27 @@ 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++)
p[i] = 0xFF;
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,
Expand All @@ -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;
Expand Down

0 comments on commit 8089ed7

Please sign in to comment.