UBI: Add self_check_eba()
self_check_eba() compares two ubi_attach_info objects. Fastmap uses this function for self checks. Signed-off-by: Richard Weinberger <richard@nod.at> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
This commit is contained in:
parent
a730665370
commit
00abf30415
@ -1201,6 +1201,102 @@ static void print_rsvd_warning(struct ubi_device *ubi,
|
|||||||
ubi->corr_peb_count);
|
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_eba_init - initialize the EBA sub-system using attaching information.
|
||||||
* @ubi: UBI device description object
|
* @ubi: UBI device description object
|
||||||
|
Loading…
x
Reference in New Issue
Block a user