UBIFS: fix recovery bug

UBIFS did not recovery in a situation in which it could
have. The relevant function assumed there could not be
more nodes in an eraseblock after a corrupted node, but
in fact the last (NAND) page written might contain anything.
The correct approach is to check for empty space (0xFF bytes)
from then on.

Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>

authored by Adrian Hunter and committed by Artem Bityutskiy de097578 963f0cf6

+23 -47
+23 -47
fs/ubifs/recovery.c
··· 425 425 * @lnum: LEB number of the LEB from which @buf was read 426 426 * @offs: offset from which @buf was read 427 427 * 428 - * This function scans @buf for more nodes and returns %0 is a node is found and 429 - * %1 if no more nodes are found. 428 + * This function ensures that the corrupted node at @offs is the last thing 429 + * written to a LEB. This function returns %1 if more data is not found and 430 + * %0 if more data is found. 430 431 */ 431 432 static int no_more_nodes(const struct ubifs_info *c, void *buf, int len, 432 433 int lnum, int offs) 433 434 { 434 - int skip, next_offs = 0; 435 + struct ubifs_ch *ch = buf; 436 + int skip, dlen = le32_to_cpu(ch->len); 435 437 436 - if (len > UBIFS_DATA_NODE_SZ) { 437 - struct ubifs_ch *ch = buf; 438 - int dlen = le32_to_cpu(ch->len); 439 - 440 - if (ch->node_type == UBIFS_DATA_NODE && dlen >= UBIFS_CH_SZ && 441 - dlen <= UBIFS_MAX_DATA_NODE_SZ) 442 - /* The corrupt node looks like a data node */ 443 - next_offs = ALIGN(offs + dlen, 8); 438 + /* Check for empty space after the corrupt node's common header */ 439 + skip = ALIGN(offs + UBIFS_CH_SZ, c->min_io_size) - offs; 440 + if (is_empty(buf + skip, len - skip)) 441 + return 1; 442 + /* 443 + * The area after the common header size is not empty, so the common 444 + * header must be intact. Check it. 445 + */ 446 + if (ubifs_check_node(c, buf, lnum, offs, 1, 0) != -EUCLEAN) { 447 + dbg_rcvry("unexpected bad common header at %d:%d", lnum, offs); 448 + return 0; 444 449 } 445 - 446 - if (c->min_io_size == 1) 447 - skip = 8; 448 - else 449 - skip = ALIGN(offs + 1, c->min_io_size) - offs; 450 - 451 - offs += skip; 452 - buf += skip; 453 - len -= skip; 454 - while (len > 8) { 455 - struct ubifs_ch *ch = buf; 456 - uint32_t magic = le32_to_cpu(ch->magic); 457 - int ret; 458 - 459 - if (magic == UBIFS_NODE_MAGIC) { 460 - ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1); 461 - if (ret == SCANNED_A_NODE || ret > 0) { 462 - /* 463 - * There is a small chance this is just data in 464 - * a data node, so check that possibility. e.g. 465 - * this is part of a file that itself contains 466 - * a UBIFS image. 467 - */ 468 - if (next_offs && offs + le32_to_cpu(ch->len) <= 469 - next_offs) 470 - continue; 471 - dbg_rcvry("unexpected node at %d:%d", lnum, 472 - offs); 473 - return 0; 474 - } 475 - } 476 - offs += 8; 477 - buf += 8; 478 - len -= 8; 479 - } 480 - return 1; 450 + /* Now we know the corrupt node's length we can skip over it */ 451 + skip = ALIGN(offs + dlen, c->min_io_size) - offs; 452 + /* After which there should be empty space */ 453 + if (is_empty(buf + skip, len - skip)) 454 + return 1; 455 + dbg_rcvry("unexpected data at %d:%d", lnum, offs + skip); 456 + return 0; 481 457 } 482 458 483 459 /**