summaryrefslogtreecommitdiff
path: root/ubi-utils/src/libubigen.c
diff options
context:
space:
mode:
Diffstat (limited to 'ubi-utils/src/libubigen.c')
-rw-r--r--ubi-utils/src/libubigen.c92
1 files changed, 57 insertions, 35 deletions
diff --git a/ubi-utils/src/libubigen.c b/ubi-utils/src/libubigen.c
index c3a0f9c..9cbd1b7 100644
--- a/ubi-utils/src/libubigen.c
+++ b/ubi-utils/src/libubigen.c
@@ -38,35 +38,6 @@
#define PROGRAM_NAME "libubigen"
/**
- * ubigen_create_empty_vtbl - creates empty volume table.
- * @size: physical eraseblock size on input, size of the volume table on output
- *
- * This function creates an empty volume table and returns a pointer to it in
- * case of success and %NULL in case of failure. The volume table size is
- * returned in @size which has to contain PEB size on input.
- */
-struct ubi_vtbl_record *ubigen_create_empty_vtbl(int *size)
-{
- struct ubi_vtbl_record *vtbl;
- int i;
-
- if (*size > UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE)
- *size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE;
-
- vtbl = calloc(1, *size);
- if (!vtbl)
- return NULL;
-
- for (i = 0; i < UBI_MAX_VOLUMES; i++) {
- uint32_t crc = crc32(UBI_CRC32_INIT, &vtbl[i],
- UBI_VTBL_RECORD_SIZE_CRC);
- vtbl[i].crc = __cpu_to_be32(crc);
- }
-
- return vtbl;
-}
-
-/**
* ubigen_info_init - initialize libubigen.
* @ui: libubigen information
* @peb_size: flash physical eraseblock size
@@ -93,28 +64,67 @@ void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size,
ui->leb_size = peb_size - ui->data_offs;
ui->ubi_ver = ubi_ver;
ui->ec = ec;
+
+ ui->vtbl_size = ui->leb_size;
+ if (ui->vtbl_size > UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE)
+ ui->vtbl_size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE;
+ ui->max_volumes = ui->vtbl_size / UBI_VTBL_RECORD_SIZE;
+}
+
+/**
+ * ubigen_create_empty_vtbl - creates empty volume table.
+ *
+ * This function creates an empty volume table and returns a pointer to it in
+ * case of success and %NULL in case of failure. The returned object has to be
+ * freed with 'free()' call.
+ */
+struct ubi_vtbl_record *ubigen_create_empty_vtbl(const struct ubigen_info *ui)
+{
+ struct ubi_vtbl_record *vtbl;
+ int i;
+
+ vtbl = calloc(1, ui->vtbl_size);
+ if (!vtbl) {
+ errmsg("cannot allocate %d bytes of memory", ui->vtbl_size);
+ return NULL;
+ }
+
+ for (i = 0; i < UBI_MAX_VOLUMES; i++) {
+ uint32_t crc = crc32(UBI_CRC32_INIT, &vtbl[i],
+ UBI_VTBL_RECORD_SIZE_CRC);
+ vtbl[i].crc = __cpu_to_be32(crc);
+ }
+
+ return vtbl;
}
/**
* ubigen_add_volume - add a volume to the volume table.
- * @vol_id: volume ID
- * @bytes: volume size in bytes
- * @alignment: volume alignment
- * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
- * @name: volume name
* @ui: libubigen information
+ * @vi: volume information
* @vtbl: volume table to add to
*
* This function adds volume described by input parameters to the volume table
* @vtbl.
*/
-void ubigen_add_volume(const struct ubigen_info *ui,
+int ubigen_add_volume(const struct ubigen_info *ui,
const struct ubigen_vol_info *vi,
struct ubi_vtbl_record *vtbl)
{
struct ubi_vtbl_record *vtbl_rec = &vtbl[vi->id];
uint32_t tmp;
+ if (vi->id >= ui->max_volumes) {
+ errmsg("too high volume id %d, max. volumes is %d",
+ vi->id, ui->max_volumes);
+ return -1;
+ }
+ if (vi->alignment >= ui->leb_size) {
+ errmsg("too large alignment %d, max is %d (LEB size)",
+ vi->alignment, ui->leb_size);
+ return -1;
+ }
+
memset(vtbl_rec, '\0', sizeof(struct ubi_vtbl_record));
tmp = (vi->bytes + ui->leb_size - 1) / ui->leb_size;
vtbl_rec->reserved_pebs = __cpu_to_be32(tmp);
@@ -129,6 +139,7 @@ void ubigen_add_volume(const struct ubigen_info *ui,
tmp = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC);
vtbl_rec->crc = __cpu_to_be32(tmp);
+ return 0;
}
/**
@@ -213,6 +224,17 @@ int ubigen_write_volume(const struct ubigen_info *ui,
int len = vi->usable_leb_size, rd, lnum = 0;
char inbuf[ui->leb_size], outbuf[ui->peb_size];
+ if (vi->id >= ui->max_volumes) {
+ errmsg("too high volume id %d, max. volumes is %d",
+ vi->id, ui->max_volumes);
+ return -1;
+ }
+ if (vi->alignment >= ui->leb_size) {
+ errmsg("too large alignment %d, max is %d (LEB size)",
+ vi->alignment, ui->leb_size);
+ return -1;
+ }
+
memset(outbuf, 0xFF, ui->data_offs);
init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf);