diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-05-16 06:41:55 -0400 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-05-16 08:48:48 -0400 |
commit | 617992069513c1e789c707c4d75ff03bf7dd0fb0 (patch) | |
tree | 04ee36190d991f0b7836fff0a666b9847bf32d92 /fs/ubifs | |
parent | 9d510db423303b4f3555074dd7bdd0d692e432a4 (diff) |
UBIFS: clean up LEB recovery function
This patch cleans up 'ubifs_recover_leb()' function and makes it more readable.
Move things which are done only once out of the loop and kill unneeded 'switch'
statement.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/recovery.c | 84 |
1 files changed, 28 insertions, 56 deletions
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 42b4512c46b0..7d922033d666 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -609,8 +609,8 @@ static int drop_incomplete_group(struct ubifs_scan_leb *sleb, int *offs) | |||
609 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | 609 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, |
610 | int offs, void *sbuf, int grouped) | 610 | int offs, void *sbuf, int grouped) |
611 | { | 611 | { |
612 | int err, len = c->leb_size - offs, need_clean = 0, quiet = 1; | 612 | int ret = 0, err, len = c->leb_size - offs, need_clean = 0; |
613 | int empty_chkd = 0, start = offs; | 613 | int start = offs; |
614 | struct ubifs_scan_leb *sleb; | 614 | struct ubifs_scan_leb *sleb; |
615 | void *buf = sbuf + offs; | 615 | void *buf = sbuf + offs; |
616 | 616 | ||
@@ -624,8 +624,6 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
624 | need_clean = 1; | 624 | need_clean = 1; |
625 | 625 | ||
626 | while (len >= 8) { | 626 | while (len >= 8) { |
627 | int ret; | ||
628 | |||
629 | dbg_scan("look at LEB %d:%d (%d bytes left)", | 627 | dbg_scan("look at LEB %d:%d (%d bytes left)", |
630 | lnum, offs, len); | 628 | lnum, offs, len); |
631 | 629 | ||
@@ -635,8 +633,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
635 | * Scan quietly until there is an error from which we cannot | 633 | * Scan quietly until there is an error from which we cannot |
636 | * recover | 634 | * recover |
637 | */ | 635 | */ |
638 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, quiet); | 636 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0); |
639 | |||
640 | if (ret == SCANNED_A_NODE) { | 637 | if (ret == SCANNED_A_NODE) { |
641 | /* A valid node, and not a padding node */ | 638 | /* A valid node, and not a padding node */ |
642 | struct ubifs_ch *ch = buf; | 639 | struct ubifs_ch *ch = buf; |
@@ -649,66 +646,37 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
649 | offs += node_len; | 646 | offs += node_len; |
650 | buf += node_len; | 647 | buf += node_len; |
651 | len -= node_len; | 648 | len -= node_len; |
652 | continue; | 649 | } else if (ret > 0) { |
653 | } | ||
654 | |||
655 | if (ret > 0) { | ||
656 | /* Padding bytes or a valid padding node */ | 650 | /* Padding bytes or a valid padding node */ |
657 | offs += ret; | 651 | offs += ret; |
658 | buf += ret; | 652 | buf += ret; |
659 | len -= ret; | 653 | len -= ret; |
660 | continue; | 654 | } else if (ret == SCANNED_EMPTY_SPACE || |
661 | } | 655 | ret == SCANNED_GARBAGE || |
662 | 656 | ret == SCANNED_A_BAD_PAD_NODE || | |
663 | if (ret == SCANNED_EMPTY_SPACE) { | 657 | ret == SCANNED_A_CORRUPT_NODE) { |
664 | if (!is_empty(buf, len)) { | 658 | dbg_rcvry("found corruption - %d", ret); |
665 | if (!is_last_write(c, buf, offs)) | ||
666 | break; | ||
667 | clean_buf(c, &buf, lnum, &offs, &len); | ||
668 | need_clean = 1; | ||
669 | } | ||
670 | empty_chkd = 1; | ||
671 | break; | 659 | break; |
672 | } | 660 | } else { |
673 | 661 | dbg_err("unexpected return value %d", ret); | |
674 | if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE) | ||
675 | if (is_last_write(c, buf, offs)) { | ||
676 | clean_buf(c, &buf, lnum, &offs, &len); | ||
677 | need_clean = 1; | ||
678 | empty_chkd = 1; | ||
679 | break; | ||
680 | } | ||
681 | |||
682 | if (ret == SCANNED_A_CORRUPT_NODE) | ||
683 | if (no_more_nodes(c, buf, len, lnum, offs)) { | ||
684 | clean_buf(c, &buf, lnum, &offs, &len); | ||
685 | need_clean = 1; | ||
686 | empty_chkd = 1; | ||
687 | break; | ||
688 | } | ||
689 | |||
690 | if (quiet) { | ||
691 | /* Redo the last scan but noisily */ | ||
692 | quiet = 0; | ||
693 | continue; | ||
694 | } | ||
695 | |||
696 | switch (ret) { | ||
697 | case SCANNED_GARBAGE: | ||
698 | dbg_err("garbage"); | ||
699 | goto corrupted; | ||
700 | case SCANNED_A_CORRUPT_NODE: | ||
701 | case SCANNED_A_BAD_PAD_NODE: | ||
702 | dbg_err("bad node"); | ||
703 | goto corrupted; | ||
704 | default: | ||
705 | dbg_err("unknown"); | ||
706 | err = -EINVAL; | 662 | err = -EINVAL; |
707 | goto error; | 663 | goto error; |
708 | } | 664 | } |
709 | } | 665 | } |
710 | 666 | ||
711 | if (!empty_chkd && !is_empty(buf, len)) { | 667 | if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE) { |
668 | if (is_last_write(c, buf, offs)) { | ||
669 | clean_buf(c, &buf, lnum, &offs, &len); | ||
670 | need_clean = 1; | ||
671 | } else | ||
672 | goto corrupted_rescan; | ||
673 | } else if (ret == SCANNED_A_CORRUPT_NODE) { | ||
674 | if (no_more_nodes(c, buf, len, lnum, offs)) { | ||
675 | clean_buf(c, &buf, lnum, &offs, &len); | ||
676 | need_clean = 1; | ||
677 | } else | ||
678 | goto corrupted_rescan; | ||
679 | } else if (!is_empty(buf, len)) { | ||
712 | if (is_last_write(c, buf, offs)) { | 680 | if (is_last_write(c, buf, offs)) { |
713 | clean_buf(c, &buf, lnum, &offs, &len); | 681 | clean_buf(c, &buf, lnum, &offs, &len); |
714 | need_clean = 1; | 682 | need_clean = 1; |
@@ -751,6 +719,10 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
751 | 719 | ||
752 | return sleb; | 720 | return sleb; |
753 | 721 | ||
722 | corrupted_rescan: | ||
723 | /* Re-scan the corrupted data with verbose messages */ | ||
724 | dbg_err("corruptio %d", ret); | ||
725 | ubifs_scan_a_node(c, buf, len, lnum, offs, 1); | ||
754 | corrupted: | 726 | corrupted: |
755 | ubifs_scanned_corruption(c, lnum, offs, buf); | 727 | ubifs_scanned_corruption(c, lnum, offs, buf); |
756 | err = -EUCLEAN; | 728 | err = -EUCLEAN; |