diff options
author | Richard Weinberger <richard@nod.at> | 2016-06-14 04:12:15 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2016-07-29 17:32:42 -0400 |
commit | fdf10ed710c0aa177e8dfcd84e65e4e5e8e0956b (patch) | |
tree | dbe8f8cb94857d85987d82f4be8cca2b7483749e /drivers/mtd/ubi/fastmap.c | |
parent | be8011053f0678792a1f0adda66fd74a5fe4adc3 (diff) |
ubi: Rework Fastmap attach base code
Introduce a new list to the UBI attach information
object to be able to deal better with old and corrupted
Fastmap eraseblocks.
Also move more Fastmap specific code into fastmap.c.
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'drivers/mtd/ubi/fastmap.c')
-rw-r--r-- | drivers/mtd/ubi/fastmap.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index ab337e67e1f3..12bdb0902327 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c | |||
@@ -850,27 +850,57 @@ fail: | |||
850 | } | 850 | } |
851 | 851 | ||
852 | /** | 852 | /** |
853 | * find_fm_anchor - find the most recent Fastmap superblock (anchor) | ||
854 | * @ai: UBI attach info to be filled | ||
855 | */ | ||
856 | static int find_fm_anchor(struct ubi_attach_info *ai) | ||
857 | { | ||
858 | int ret = -1; | ||
859 | struct ubi_ainf_peb *aeb; | ||
860 | unsigned long long max_sqnum = 0; | ||
861 | |||
862 | list_for_each_entry(aeb, &ai->fastmap, u.list) { | ||
863 | if (aeb->vol_id == UBI_FM_SB_VOLUME_ID && aeb->sqnum > max_sqnum) { | ||
864 | max_sqnum = aeb->sqnum; | ||
865 | ret = aeb->pnum; | ||
866 | } | ||
867 | } | ||
868 | |||
869 | return ret; | ||
870 | } | ||
871 | |||
872 | /** | ||
853 | * ubi_scan_fastmap - scan the fastmap. | 873 | * ubi_scan_fastmap - scan the fastmap. |
854 | * @ubi: UBI device object | 874 | * @ubi: UBI device object |
855 | * @ai: UBI attach info to be filled | 875 | * @ai: UBI attach info to be filled |
856 | * @fm_anchor: The fastmap starts at this PEB | 876 | * @scan_ai: UBI attach info from the first 64 PEBs, |
877 | * used to find the most recent Fastmap data structure | ||
857 | * | 878 | * |
858 | * Returns 0 on success, UBI_NO_FASTMAP if no fastmap was found, | 879 | * Returns 0 on success, UBI_NO_FASTMAP if no fastmap was found, |
859 | * UBI_BAD_FASTMAP if one was found but is not usable. | 880 | * UBI_BAD_FASTMAP if one was found but is not usable. |
860 | * < 0 indicates an internal error. | 881 | * < 0 indicates an internal error. |
861 | */ | 882 | */ |
862 | int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, | 883 | int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, |
863 | int fm_anchor) | 884 | struct ubi_attach_info *scan_ai) |
864 | { | 885 | { |
865 | struct ubi_fm_sb *fmsb, *fmsb2; | 886 | struct ubi_fm_sb *fmsb, *fmsb2; |
866 | struct ubi_vid_hdr *vh; | 887 | struct ubi_vid_hdr *vh; |
867 | struct ubi_ec_hdr *ech; | 888 | struct ubi_ec_hdr *ech; |
868 | struct ubi_fastmap_layout *fm; | 889 | struct ubi_fastmap_layout *fm; |
869 | int i, used_blocks, pnum, ret = 0; | 890 | struct ubi_ainf_peb *tmp_aeb, *aeb; |
891 | int i, used_blocks, pnum, fm_anchor, ret = 0; | ||
870 | size_t fm_size; | 892 | size_t fm_size; |
871 | __be32 crc, tmp_crc; | 893 | __be32 crc, tmp_crc; |
872 | unsigned long long sqnum = 0; | 894 | unsigned long long sqnum = 0; |
873 | 895 | ||
896 | fm_anchor = find_fm_anchor(scan_ai); | ||
897 | if (fm_anchor < 0) | ||
898 | return UBI_NO_FASTMAP; | ||
899 | |||
900 | /* Move all (possible) fastmap blocks into our new attach structure. */ | ||
901 | list_for_each_entry_safe(aeb, tmp_aeb, &scan_ai->fastmap, u.list) | ||
902 | list_move_tail(&aeb->u.list, &ai->fastmap); | ||
903 | |||
874 | down_write(&ubi->fm_protect); | 904 | down_write(&ubi->fm_protect); |
875 | memset(ubi->fm_buf, 0, ubi->fm_size); | 905 | memset(ubi->fm_buf, 0, ubi->fm_size); |
876 | 906 | ||