Loading drivers/mtd/ubi/eba.c +96 −0 Original line number Diff line number Diff line Loading @@ -1201,6 +1201,102 @@ static void print_rsvd_warning(struct ubi_device *ubi, ubi->corr_peb_count); } /** * self_check_eba - run a self check on the EBA table constructed by fastmap. * @ubi: UBI device description object * @ai_fastmap: UBI attach info object created by fastmap * @ai_scan: UBI attach info object created by scanning * * Returns < 0 in case of an internal error, 0 otherwise. * If a bad EBA table entry was found it will be printed out and * ubi_assert() triggers. */ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, struct ubi_attach_info *ai_scan) { int i, j, num_volumes, ret = 0; int **scan_eba, **fm_eba; struct ubi_ainf_volume *av; struct ubi_volume *vol; struct ubi_ainf_peb *aeb; struct rb_node *rb; num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; scan_eba = kmalloc(sizeof(*scan_eba) * num_volumes, GFP_KERNEL); if (!scan_eba) return -ENOMEM; fm_eba = kmalloc(sizeof(*fm_eba) * num_volumes, GFP_KERNEL); if (!fm_eba) { kfree(scan_eba); return -ENOMEM; } for (i = 0; i < num_volumes; i++) { vol = ubi->volumes[i]; if (!vol) continue; scan_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**scan_eba), GFP_KERNEL); if (!scan_eba[i]) { ret = -ENOMEM; goto out_free; } fm_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**fm_eba), GFP_KERNEL); if (!fm_eba[i]) { ret = -ENOMEM; goto out_free; } for (j = 0; j < vol->reserved_pebs; j++) scan_eba[i][j] = fm_eba[i][j] = UBI_LEB_UNMAPPED; av = ubi_find_av(ai_scan, idx2vol_id(ubi, i)); if (!av) continue; ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) scan_eba[i][aeb->lnum] = aeb->pnum; av = ubi_find_av(ai_fastmap, idx2vol_id(ubi, i)); if (!av) continue; ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) fm_eba[i][aeb->lnum] = aeb->pnum; for (j = 0; j < vol->reserved_pebs; j++) { if (scan_eba[i][j] != fm_eba[i][j]) { if (scan_eba[i][j] == UBI_LEB_UNMAPPED || fm_eba[i][j] == UBI_LEB_UNMAPPED) continue; ubi_err("LEB:%i:%i is PEB:%i instead of %i!", vol->vol_id, i, fm_eba[i][j], scan_eba[i][j]); ubi_assert(0); } } } out_free: for (i = 0; i < num_volumes; i++) { if (!ubi->volumes[i]) continue; kfree(scan_eba[i]); kfree(fm_eba[i]); } kfree(scan_eba); kfree(fm_eba); return ret; } /** * ubi_eba_init - initialize the EBA sub-system using attaching information. * @ubi: UBI device description object Loading Loading
drivers/mtd/ubi/eba.c +96 −0 Original line number Diff line number Diff line Loading @@ -1201,6 +1201,102 @@ static void print_rsvd_warning(struct ubi_device *ubi, ubi->corr_peb_count); } /** * self_check_eba - run a self check on the EBA table constructed by fastmap. * @ubi: UBI device description object * @ai_fastmap: UBI attach info object created by fastmap * @ai_scan: UBI attach info object created by scanning * * Returns < 0 in case of an internal error, 0 otherwise. * If a bad EBA table entry was found it will be printed out and * ubi_assert() triggers. */ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, struct ubi_attach_info *ai_scan) { int i, j, num_volumes, ret = 0; int **scan_eba, **fm_eba; struct ubi_ainf_volume *av; struct ubi_volume *vol; struct ubi_ainf_peb *aeb; struct rb_node *rb; num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; scan_eba = kmalloc(sizeof(*scan_eba) * num_volumes, GFP_KERNEL); if (!scan_eba) return -ENOMEM; fm_eba = kmalloc(sizeof(*fm_eba) * num_volumes, GFP_KERNEL); if (!fm_eba) { kfree(scan_eba); return -ENOMEM; } for (i = 0; i < num_volumes; i++) { vol = ubi->volumes[i]; if (!vol) continue; scan_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**scan_eba), GFP_KERNEL); if (!scan_eba[i]) { ret = -ENOMEM; goto out_free; } fm_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**fm_eba), GFP_KERNEL); if (!fm_eba[i]) { ret = -ENOMEM; goto out_free; } for (j = 0; j < vol->reserved_pebs; j++) scan_eba[i][j] = fm_eba[i][j] = UBI_LEB_UNMAPPED; av = ubi_find_av(ai_scan, idx2vol_id(ubi, i)); if (!av) continue; ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) scan_eba[i][aeb->lnum] = aeb->pnum; av = ubi_find_av(ai_fastmap, idx2vol_id(ubi, i)); if (!av) continue; ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) fm_eba[i][aeb->lnum] = aeb->pnum; for (j = 0; j < vol->reserved_pebs; j++) { if (scan_eba[i][j] != fm_eba[i][j]) { if (scan_eba[i][j] == UBI_LEB_UNMAPPED || fm_eba[i][j] == UBI_LEB_UNMAPPED) continue; ubi_err("LEB:%i:%i is PEB:%i instead of %i!", vol->vol_id, i, fm_eba[i][j], scan_eba[i][j]); ubi_assert(0); } } } out_free: for (i = 0; i < num_volumes; i++) { if (!ubi->volumes[i]) continue; kfree(scan_eba[i]); kfree(fm_eba[i]); } kfree(scan_eba); kfree(fm_eba); return ret; } /** * ubi_eba_init - initialize the EBA sub-system using attaching information. * @ubi: UBI device description object Loading