Commit 2765df7d authored by Artem Bityutskiy's avatar Artem Bityutskiy

UBIFS: use max_write_size during recovery

When recovering from unclean reboots UBIFS scans the journal and checks nodes.
If a corrupted node is found, UBIFS tries to check if this is the last node
in the LEB or not. This is is done by checking if there only 0xFF bytes
starting from the next min. I/O unit. However, since now we write in
c->max_write_size, we should actually check for 0xFFs starting from the
next max. write unit.
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
parent 6c7f74f7
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
* UBIFS writes only to erased LEBs, so it writes only to the flash space * UBIFS writes only to erased LEBs, so it writes only to the flash space
* containing only 0xFFs. UBIFS also always writes strictly from the beginning * containing only 0xFFs. UBIFS also always writes strictly from the beginning
* of the LEB to the end. And UBIFS assumes that the underlying flash media * of the LEB to the end. And UBIFS assumes that the underlying flash media
* writes in @c->min_io_unit bytes at a time. * writes in @c->max_write_size bytes at a time.
* *
* Hence, if UBIFS finds a corrupted node at offset X, it expects only the min. * Hence, if UBIFS finds a corrupted node at offset X, it expects only the min.
* I/O unit corresponding to offset X to contain corrupted data, all the * I/O unit corresponding to offset X to contain corrupted data, all the
...@@ -380,7 +380,8 @@ int ubifs_write_rcvrd_mst_node(struct ubifs_info *c) ...@@ -380,7 +380,8 @@ int ubifs_write_rcvrd_mst_node(struct ubifs_info *c)
* *
* This function returns %1 if @offs was in the last write to the LEB whose data * This function returns %1 if @offs was in the last write to the LEB whose data
* is in @buf, otherwise %0 is returned. The determination is made by checking * is in @buf, otherwise %0 is returned. The determination is made by checking
* for subsequent empty space starting from the next @c->min_io_size boundary. * for subsequent empty space starting from the next @c->max_write_size
* boundary.
*/ */
static int is_last_write(const struct ubifs_info *c, void *buf, int offs) static int is_last_write(const struct ubifs_info *c, void *buf, int offs)
{ {
...@@ -388,10 +389,10 @@ static int is_last_write(const struct ubifs_info *c, void *buf, int offs) ...@@ -388,10 +389,10 @@ static int is_last_write(const struct ubifs_info *c, void *buf, int offs)
uint8_t *p; uint8_t *p;
/* /*
* Round up to the next @c->min_io_size boundary i.e. @offs is in the * Round up to the next @c->max_write_size boundary i.e. @offs is in
* last wbuf written. After that should be empty space. * the last wbuf written. After that should be empty space.
*/ */
empty_offs = ALIGN(offs + 1, c->min_io_size); empty_offs = ALIGN(offs + 1, c->max_write_size);
check_len = c->leb_size - empty_offs; check_len = c->leb_size - empty_offs;
p = buf + empty_offs - offs; p = buf + empty_offs - offs;
return is_empty(p, check_len); return is_empty(p, check_len);
...@@ -446,7 +447,7 @@ static int no_more_nodes(const struct ubifs_info *c, void *buf, int len, ...@@ -446,7 +447,7 @@ static int no_more_nodes(const struct ubifs_info *c, void *buf, int len,
int skip, dlen = le32_to_cpu(ch->len); int skip, dlen = le32_to_cpu(ch->len);
/* Check for empty space after the corrupt node's common header */ /* Check for empty space after the corrupt node's common header */
skip = ALIGN(offs + UBIFS_CH_SZ, c->min_io_size) - offs; skip = ALIGN(offs + UBIFS_CH_SZ, c->max_write_size) - offs;
if (is_empty(buf + skip, len - skip)) if (is_empty(buf + skip, len - skip))
return 1; return 1;
/* /*
...@@ -458,7 +459,7 @@ static int no_more_nodes(const struct ubifs_info *c, void *buf, int len, ...@@ -458,7 +459,7 @@ static int no_more_nodes(const struct ubifs_info *c, void *buf, int len,
return 0; return 0;
} }
/* Now we know the corrupt node's length we can skip over it */ /* Now we know the corrupt node's length we can skip over it */
skip = ALIGN(offs + dlen, c->min_io_size) - offs; skip = ALIGN(offs + dlen, c->max_write_size) - offs;
/* After which there should be empty space */ /* After which there should be empty space */
if (is_empty(buf + skip, len - skip)) if (is_empty(buf + skip, len - skip))
return 1; return 1;
...@@ -857,12 +858,8 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, ...@@ -857,12 +858,8 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
static int recover_head(const struct ubifs_info *c, int lnum, int offs, static int recover_head(const struct ubifs_info *c, int lnum, int offs,
void *sbuf) void *sbuf)
{ {
int len, err; int len = c->max_write_size, err;
if (c->min_io_size > 1)
len = c->min_io_size;
else
len = 512;
if (offs + len > c->leb_size) if (offs + len > c->leb_size)
len = c->leb_size - offs; len = c->leb_size - offs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment