aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-02-02 02:22:54 -0500
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-03-08 03:12:49 -0500
commit2765df7da540687c4d57ca840182122f074c5b9c (patch)
treec3dcf4c3ae4c6596ca0ac61a119274b7b4e782c4 /fs
parent6c7f74f703cc4baf053270a6e78a32f832f03445 (diff)
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: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ubifs/recovery.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index e2714f8f05ff..936f2cbfe6b6 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -38,7 +38,7 @@
38 * UBIFS writes only to erased LEBs, so it writes only to the flash space 38 * UBIFS writes only to erased LEBs, so it writes only to the flash space
39 * containing only 0xFFs. UBIFS also always writes strictly from the beginning 39 * containing only 0xFFs. UBIFS also always writes strictly from the beginning
40 * of the LEB to the end. And UBIFS assumes that the underlying flash media 40 * of the LEB to the end. And UBIFS assumes that the underlying flash media
41 * writes in @c->min_io_unit bytes at a time. 41 * writes in @c->max_write_size bytes at a time.
42 * 42 *
43 * Hence, if UBIFS finds a corrupted node at offset X, it expects only the min. 43 * Hence, if UBIFS finds a corrupted node at offset X, it expects only the min.
44 * I/O unit corresponding to offset X to contain corrupted data, all the 44 * I/O unit corresponding to offset X to contain corrupted data, all the
@@ -379,8 +379,9 @@ int ubifs_write_rcvrd_mst_node(struct ubifs_info *c)
379 * @offs: offset to check 379 * @offs: offset to check
380 * 380 *
381 * This function returns %1 if @offs was in the last write to the LEB whose data 381 * This function returns %1 if @offs was in the last write to the LEB whose data
382 * is in @buf, otherwise %0 is returned. The determination is made by checking 382 * is in @buf, otherwise %0 is returned. The determination is made by checking
383 * for subsequent empty space starting from the next @c->min_io_size boundary. 383 * for subsequent empty space starting from the next @c->max_write_size
384 * boundary.
384 */ 385 */
385static int is_last_write(const struct ubifs_info *c, void *buf, int offs) 386static int is_last_write(const struct ubifs_info *c, void *buf, int offs)
386{ 387{
@@ -388,10 +389,10 @@ static int is_last_write(const struct ubifs_info *c, void *buf, int offs)
388 uint8_t *p; 389 uint8_t *p;
389 390
390 /* 391 /*
391 * Round up to the next @c->min_io_size boundary i.e. @offs is in the 392 * Round up to the next @c->max_write_size boundary i.e. @offs is in
392 * last wbuf written. After that should be empty space. 393 * the last wbuf written. After that should be empty space.
393 */ 394 */
394 empty_offs = ALIGN(offs + 1, c->min_io_size); 395 empty_offs = ALIGN(offs + 1, c->max_write_size);
395 check_len = c->leb_size - empty_offs; 396 check_len = c->leb_size - empty_offs;
396 p = buf + empty_offs - offs; 397 p = buf + empty_offs - offs;
397 return is_empty(p, check_len); 398 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 int skip, dlen = le32_to_cpu(ch->len); 447 int skip, dlen = le32_to_cpu(ch->len);
447 448
448 /* Check for empty space after the corrupt node's common header */ 449 /* Check for empty space after the corrupt node's common header */
449 skip = ALIGN(offs + UBIFS_CH_SZ, c->min_io_size) - offs; 450 skip = ALIGN(offs + UBIFS_CH_SZ, c->max_write_size) - offs;
450 if (is_empty(buf + skip, len - skip)) 451 if (is_empty(buf + skip, len - skip))
451 return 1; 452 return 1;
452 /* 453 /*
@@ -458,7 +459,7 @@ static int no_more_nodes(const struct ubifs_info *c, void *buf, int len,
458 return 0; 459 return 0;
459 } 460 }
460 /* Now we know the corrupt node's length we can skip over it */ 461 /* Now we know the corrupt node's length we can skip over it */
461 skip = ALIGN(offs + dlen, c->min_io_size) - offs; 462 skip = ALIGN(offs + dlen, c->max_write_size) - offs;
462 /* After which there should be empty space */ 463 /* After which there should be empty space */
463 if (is_empty(buf + skip, len - skip)) 464 if (is_empty(buf + skip, len - skip))
464 return 1; 465 return 1;
@@ -857,12 +858,8 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
857static int recover_head(const struct ubifs_info *c, int lnum, int offs, 858static int recover_head(const struct ubifs_info *c, int lnum, int offs,
858 void *sbuf) 859 void *sbuf)
859{ 860{
860 int len, err; 861 int len = c->max_write_size, err;
861 862
862 if (c->min_io_size > 1)
863 len = c->min_io_size;
864 else
865 len = 512;
866 if (offs + len > c->leb_size) 863 if (offs + len > c->leb_size)
867 len = c->leb_size - offs; 864 len = c->leb_size - offs;
868 865