int ubigen_write_complete(ubi_info_t u) { size_t i; int rc = 0; for (i = 0; i < u->leb_total; i++) { rc = ubigen_write_leb(u, NO_ERROR); if (rc != 0) return rc; } return 0; }
int ubigen_write_broken_update(ubi_info_t u, uint32_t blk) { int rc = 0; rc = skip_blks(u, blk); if (rc != 0) return rc; rc = ubigen_write_leb(u, MARK_AS_UPDATE | BROKEN_DATA_CRC); if (rc != 0) return rc; return 0; }
/** * @brief Builds a UBI volume table from a volume entry list. * @return 0 On success. * else Error. */ static int write_ubi_volume_table(pdd_data_t pdd, list_t raw_pebs, struct ubi_vtbl_record *vol_tab, size_t vol_tab_size, size_t *ebs_written, io_t io) { int rc = 0; ubi_info_t u; peb_t raw_peb; peb_t cmp_peb; size_t leb_size, leb_total, j = 0; uint8_t *ptr = NULL; FILE* fp_leb = NULL; int vt_slots; size_t vol_tab_size_limit; rc = peb_new(0, 0, &cmp_peb); if (rc != 0) goto err; /* @FIXME: Artem creates one volume with 2 LEBs. * IMO 2 volumes would be more convenient. In order * to get 2 reserved LEBs from ubigen, I have to * introduce this stupid mechanism. Until no final * decision of the VTAB structure is made... Good enough. */ rc = ubigen_create(&u, UBI_LAYOUT_VOLUME_ID, UBI_VID_DYNAMIC, pdd->eb_size, DEFAULT_ERASE_COUNT, 1, UBI_VERSION, pdd->vid_hdr_offset, UBI_COMPAT_REJECT, vol_tab_size, stdin, io->fp_out); /* @FIXME stdin for fp_in is a hack */ if (rc != 0) goto err; rc = ubigen_get_leb_size(u, &leb_size); if (rc != 0) goto err; ubigen_destroy(&u); /* * The number of supported volumes is restricted by the eraseblock size * and by the UBI_MAX_VOLUMES constant. */ vt_slots = leb_size / UBI_VTBL_RECORD_SIZE; if (vt_slots > UBI_MAX_VOLUMES) vt_slots = UBI_MAX_VOLUMES; vol_tab_size_limit = vt_slots * UBI_VTBL_RECORD_SIZE; ptr = (uint8_t*) malloc(leb_size * sizeof(uint8_t)); if (ptr == NULL) goto err; memset(ptr, 0xff, leb_size); memcpy(ptr, vol_tab, vol_tab_size_limit); fp_leb = my_fmemopen(ptr, leb_size, "r"); rc = ubigen_create(&u, UBI_LAYOUT_VOLUME_ID, UBI_VID_DYNAMIC, pdd->eb_size, DEFAULT_ERASE_COUNT, 1, UBI_VERSION, pdd->vid_hdr_offset, UBI_COMPAT_REJECT, leb_size * UBI_LAYOUT_VOLUME_EBS, fp_leb, io->fp_out); if (rc != 0) goto err; rc = ubigen_get_leb_total(u, &leb_total); if (rc != 0) goto err; long old_file_pos = ftell(fp_leb); while(j < leb_total) { rc = fseek(fp_leb, old_file_pos, SEEK_SET); if (rc != 0) goto err; cmp_peb->num = *ebs_written; raw_peb = is_in((cmp_func_t)peb_cmp, cmp_peb, raw_pebs); if (raw_peb) { rc = peb_write(io->fp_out, raw_peb); } else { rc = ubigen_write_leb(u, NO_ERROR); j++; } if (rc != 0) goto err; (*ebs_written)++; } err: free(ptr); peb_free(&cmp_peb); ubigen_destroy(&u); fclose(fp_leb); return rc; }
static int convert_ubi_volume(pfi_ubi_t ubi, pdd_data_t pdd, list_t raw_pebs, struct ubi_vtbl_record *vol_tab, size_t *ebs_written, io_t io) { int rc = 0; uint32_t i, j; peb_t raw_peb; peb_t cmp_peb; ubi_info_t u; size_t leb_total = 0; uint8_t vol_type; switch (ubi->type) { case pfi_ubi_static: vol_type = UBI_VID_STATIC; break; case pfi_ubi_dynamic: vol_type = UBI_VID_DYNAMIC; break; default: vol_type = UBI_VID_DYNAMIC; } rc = peb_new(0, 0, &cmp_peb); if (rc != 0) goto err; long old_file_pos = ftell(io->fp_pfi); for (i = 0; i < ubi->ids_size; i++) { rc = fseek(io->fp_pfi, old_file_pos, SEEK_SET); if (rc != 0) goto err; rc = ubigen_create(&u, ubi->ids[i], vol_type, pdd->eb_size, DEFAULT_ERASE_COUNT, ubi->alignment, UBI_VERSION, pdd->vid_hdr_offset, 0, ubi->data_size, io->fp_pfi, io->fp_out); if (rc != 0) goto err; rc = ubigen_get_leb_total(u, &leb_total); if (rc != 0) goto err; j = 0; while(j < leb_total) { cmp_peb->num = *ebs_written; raw_peb = is_in((cmp_func_t)peb_cmp, cmp_peb, raw_pebs); if (raw_peb) { rc = peb_write(io->fp_out, raw_peb); } else { rc = ubigen_write_leb(u, NO_ERROR); j++; } if (rc != 0) goto err; (*ebs_written)++; } /* memorize volume table entry */ rc = ubigen_set_lvol_rec(u, ubi->size, ubi->names[i], (void*) &vol_tab[ubi->ids[i]]); if (rc != 0) goto err; ubigen_destroy(&u); } peb_free(&cmp_peb); return 0; err: peb_free(&cmp_peb); ubigen_destroy(&u); return rc; }