static void display_volume_info(struct ubi_device *ubi) { int i; for (i = 0; i < (ubi->vtbl_slots + 1); i++) { if (!ubi->volumes[i]) continue; /* Empty record */ ubi_dump_vol_info(ubi->volumes[i]); } }
/** * self_check_volume - check volume information. * @ubi: UBI device description object * @vol_id: volume ID * * Returns zero if volume is all right and a a negative error code if not. */ static int self_check_volume(struct ubi_device *ubi, int vol_id) { int idx = vol_id2idx(ubi, vol_id); int reserved_pebs, alignment, data_pad, vol_type, name_len, upd_marker; const struct ubi_volume *vol; long long n; const char *name; reserved_pebs = be32_to_cpu(ubi->vtbl[vol_id].reserved_pebs); vol = ubi->volumes[idx]; if (!vol) { if (reserved_pebs) { ubi_err(ubi, "no volume info, but volume exists"); goto fail; } return 0; } if (vol->reserved_pebs < 0 || vol->alignment < 0 || vol->data_pad < 0 || vol->name_len < 0) { ubi_err(ubi, "negative values"); goto fail; } if (vol->alignment > ubi->leb_size || vol->alignment == 0) { ubi_err(ubi, "bad alignment"); goto fail; } n = vol->alignment & (ubi->min_io_size - 1); if (vol->alignment != 1 && n) { ubi_err(ubi, "alignment is not multiple of min I/O unit"); goto fail; } n = ubi->leb_size % vol->alignment; if (vol->data_pad != n) { ubi_err(ubi, "bad data_pad, has to be %lld", n); goto fail; } if (vol->vol_type != UBI_DYNAMIC_VOLUME && vol->vol_type != UBI_STATIC_VOLUME) { ubi_err(ubi, "bad vol_type"); goto fail; } if (vol->upd_marker && vol->corrupted) { ubi_err(ubi, "update marker and corrupted simultaneously"); goto fail; } if (vol->reserved_pebs > ubi->good_peb_count) { ubi_err(ubi, "too large reserved_pebs"); goto fail; } n = ubi->leb_size - vol->data_pad; if (vol->usable_leb_size != ubi->leb_size - vol->data_pad) { ubi_err(ubi, "bad usable_leb_size, has to be %lld", n); goto fail; } if (vol->name_len > UBI_VOL_NAME_MAX) { ubi_err(ubi, "too long volume name, max is %d", UBI_VOL_NAME_MAX); goto fail; } n = strnlen(vol->name, vol->name_len + 1); if (n != vol->name_len) { ubi_err(ubi, "bad name_len %lld", n); goto fail; } n = (long long)vol->used_ebs * vol->usable_leb_size; if (vol->vol_type == UBI_DYNAMIC_VOLUME) { if (vol->corrupted) { ubi_err(ubi, "corrupted dynamic volume"); goto fail; } if (vol->used_ebs != vol->reserved_pebs) { ubi_err(ubi, "bad used_ebs"); goto fail; } if (vol->last_eb_bytes != vol->usable_leb_size) { ubi_err(ubi, "bad last_eb_bytes"); goto fail; } if (vol->used_bytes != n) { ubi_err(ubi, "bad used_bytes"); goto fail; } } else { if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) { ubi_err(ubi, "bad used_ebs"); goto fail; } if (vol->last_eb_bytes < 0 || vol->last_eb_bytes > vol->usable_leb_size) { ubi_err(ubi, "bad last_eb_bytes"); goto fail; } if (vol->used_bytes < 0 || vol->used_bytes > n || vol->used_bytes < n - vol->usable_leb_size) { ubi_err(ubi, "bad used_bytes"); goto fail; } } alignment = be32_to_cpu(ubi->vtbl[vol_id].alignment); data_pad = be32_to_cpu(ubi->vtbl[vol_id].data_pad); name_len = be16_to_cpu(ubi->vtbl[vol_id].name_len); upd_marker = ubi->vtbl[vol_id].upd_marker; name = &ubi->vtbl[vol_id].name[0]; if (ubi->vtbl[vol_id].vol_type == UBI_VID_DYNAMIC) vol_type = UBI_DYNAMIC_VOLUME; else vol_type = UBI_STATIC_VOLUME; if (alignment != vol->alignment || data_pad != vol->data_pad || upd_marker != vol->upd_marker || vol_type != vol->vol_type || name_len != vol->name_len || strncmp(name, vol->name, name_len)) { ubi_err(ubi, "volume info is different"); goto fail; } return 0; fail: ubi_err(ubi, "self-check failed for volume %d", vol_id); if (vol) ubi_dump_vol_info(vol); ubi_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); dump_stack(); return -EINVAL; }