aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/recovery.c29
1 files changed, 9 insertions, 20 deletions
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index 7d922033d666..4d10b6e36ec4 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -609,7 +609,7 @@ 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 ret = 0, err, len = c->leb_size - offs, need_clean = 0; 612 int ret = 0, err, len = c->leb_size - offs;
613 int 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;
@@ -620,9 +620,6 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
620 if (IS_ERR(sleb)) 620 if (IS_ERR(sleb))
621 return sleb; 621 return sleb;
622 622
623 if (sleb->ecc)
624 need_clean = 1;
625
626 while (len >= 8) { 623 while (len >= 8) {
627 dbg_scan("look at LEB %d:%d (%d bytes left)", 624 dbg_scan("look at LEB %d:%d (%d bytes left)",
628 lnum, offs, len); 625 lnum, offs, len);
@@ -665,21 +662,18 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
665 } 662 }
666 663
667 if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE) { 664 if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE) {
668 if (is_last_write(c, buf, offs)) { 665 if (is_last_write(c, buf, offs))
669 clean_buf(c, &buf, lnum, &offs, &len); 666 clean_buf(c, &buf, lnum, &offs, &len);
670 need_clean = 1; 667 else
671 } else
672 goto corrupted_rescan; 668 goto corrupted_rescan;
673 } else if (ret == SCANNED_A_CORRUPT_NODE) { 669 } else if (ret == SCANNED_A_CORRUPT_NODE) {
674 if (no_more_nodes(c, buf, len, lnum, offs)) { 670 if (no_more_nodes(c, buf, len, lnum, offs))
675 clean_buf(c, &buf, lnum, &offs, &len); 671 clean_buf(c, &buf, lnum, &offs, &len);
676 need_clean = 1; 672 else
677 } else
678 goto corrupted_rescan; 673 goto corrupted_rescan;
679 } else if (!is_empty(buf, len)) { 674 } else if (!is_empty(buf, len)) {
680 if (is_last_write(c, buf, offs)) { 675 if (is_last_write(c, buf, offs)) {
681 clean_buf(c, &buf, lnum, &offs, &len); 676 clean_buf(c, &buf, lnum, &offs, &len);
682 need_clean = 1;
683 } else { 677 } else {
684 int corruption = first_non_ff(buf, len); 678 int corruption = first_non_ff(buf, len);
685 679
@@ -701,21 +695,16 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
701 buf = sbuf + offs; 695 buf = sbuf + offs;
702 len = c->leb_size - offs; 696 len = c->leb_size - offs;
703 clean_buf(c, &buf, lnum, &offs, &len); 697 clean_buf(c, &buf, lnum, &offs, &len);
704 need_clean = 1;
705 } 698 }
706 699
707 if (offs % c->min_io_size) { 700 if (offs % c->min_io_size)
708 clean_buf(c, &buf, lnum, &offs, &len); 701 clean_buf(c, &buf, lnum, &offs, &len);
709 need_clean = 1;
710 }
711 702
712 ubifs_end_scan(c, sleb, lnum, offs); 703 ubifs_end_scan(c, sleb, lnum, offs);
713 704
714 if (need_clean) { 705 err = fix_unclean_leb(c, sleb, start);
715 err = fix_unclean_leb(c, sleb, start); 706 if (err)
716 if (err) 707 goto error;
717 goto error;
718 }
719 708
720 return sleb; 709 return sleb;
721 710