aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-05-16 06:41:55 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-05-16 08:48:48 -0400
commit617992069513c1e789c707c4d75ff03bf7dd0fb0 (patch)
tree04ee36190d991f0b7836fff0a666b9847bf32d92 /fs/ubifs
parent9d510db423303b4f3555074dd7bdd0d692e432a4 (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.c84
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)
609struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, 609struct 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
722corrupted_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);
754corrupted: 726corrupted:
755 ubifs_scanned_corruption(c, lnum, offs, buf); 727 ubifs_scanned_corruption(c, lnum, offs, buf);
756 err = -EUCLEAN; 728 err = -EUCLEAN;