Skip to content

Commit

Permalink
refactor extended primary partition handling
Browse files Browse the repository at this point in the history
* Renamed partition->extended to partition->logical
* Track extended partition record in the partition list and hdimage
* Clean up unnecessary code

Signed-off-by: Jan Čermák <[email protected]>
  • Loading branch information
sairon committed Jun 3, 2024
1 parent c570141 commit b8a276e
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 54 deletions.
2 changes: 1 addition & 1 deletion genimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct partition {
unsigned long long align;
unsigned char partition_type;
cfg_bool_t bootable;
cfg_bool_t extended;
cfg_bool_t logical;
cfg_bool_t forced_primary;
cfg_bool_t read_only;
cfg_bool_t hidden;
Expand Down
99 changes: 46 additions & 53 deletions image-hd.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@
#define TYPE_GPT 2
#define TYPE_HYBRID (TYPE_MBR|TYPE_GPT)

#define PARTITION_TYPE_EXTENDED 0x0F

struct hdimage {
unsigned int extended_partition;
unsigned int extended_partition_index;
struct partition *extended_partition;
unsigned long long align;
unsigned long long extended_lba;
unsigned long long extended_size;
uint32_t disksig;
const char *disk_uuid;
int table_type;
Expand Down Expand Up @@ -138,7 +139,7 @@ static int hdimage_insert_mbr(struct image *image, struct list_head *partitions)
struct hdimage *hd = image->handler_priv;
struct mbr_tail mbr;
struct partition *part;
int ret, i = 0, extended_written = 0;
int ret, i = 0;

if (hd->table_type == TYPE_HYBRID) {
image_info(image, "writing hybrid MBR\n");
Expand All @@ -152,44 +153,24 @@ static int hdimage_insert_mbr(struct image *image, struct list_head *partitions)
list_for_each_entry(part, partitions, list) {
struct mbr_partition_entry *entry;

if (!part->in_partition_table)
if (!part->in_partition_table || part->logical)
continue;

if (hd->table_type == TYPE_HYBRID && !part->partition_type)
continue;

if (hd->table_type == TYPE_HYBRID && part->extended)
continue;

if (part->extended && extended_written)
continue;

entry = &mbr.part_entry[i];

entry->boot = part->bootable ? 0x80 : 0x00;
if (!part->extended) {
entry->partition_type = part->partition_type;
entry->relative_sectors = part->offset/512;
entry->total_sectors = part->size/512;
}
else {
entry->partition_type = 0x0F;
entry->relative_sectors = (hd->extended_lba)/512;
entry->total_sectors = hd->extended_size/512;
}
entry->partition_type = part->partition_type;
entry->relative_sectors = part->offset/512;
entry->total_sectors = part->size/512;
hdimage_setup_chs(entry);

image_debug(image, "[MBR entry %d]: type=%x start=%d size=%d\n",
i, entry->partition_type,
entry->relative_sectors, entry->total_sectors);

if (part->extended) {
if (!extended_written) {
extended_written = 1;
i++;
}
continue;
}
i++;
}

Expand Down Expand Up @@ -243,12 +224,12 @@ static int hdimage_insert_ebr(struct image *image, struct partition *part)
hdimage_setup_chs(entry);
struct partition *p = part;
list_for_each_entry_continue(p, &image->partitions, list) {
if (!p->extended)
if (!p->logical)
continue;
++entry;
entry->boot = 0x00;
entry->partition_type = 0x0F;
entry->relative_sectors = (p->offset - hd->align - hd->extended_lba)/512;
entry->partition_type = PARTITION_TYPE_EXTENDED;
entry->relative_sectors = (p->offset - hd->align - hd->extended_partition->offset)/512;
entry->total_sectors = (p->size + hd->align)/512;
hdimage_setup_chs(entry);
break;
Expand Down Expand Up @@ -591,13 +572,15 @@ static int hdimage_generate(struct image *image)
list_for_each_entry(part, &image->partitions, list) {
struct image *child;

image_info(image, "adding partition '%s'%s%s%s%s ...\n", part->name,
image_info(image, "adding %s partition '%s'%s%s%s%s ...\n",
part->logical ? "logical" : "primary",
part->name,
part->in_partition_table ? " (in MBR)" : "",
part->image ? " from '": "",
part->image ? part->image : "",
part->image ? "'" : "");

if (part->extended) {
if (part->logical) {
ret = hdimage_insert_ebr(image, part);
if (ret) {
image_error(image, "failed to write EBR\n");
Expand Down Expand Up @@ -777,7 +760,7 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
struct partition *gpt_backup = NULL;

hd->align = cfg_getint_suffix(cfg, "align");
hd->extended_partition = cfg_getint(cfg, "extended-partition");
hd->extended_partition_index = cfg_getint(cfg, "extended-partition");
disk_signature = cfg_getstr(cfg, "disk-signature");
table_type = cfg_getstr(cfg, "partition-table-type");
hd->gpt_location = cfg_getint_suffix(cfg, "gpt-location");
Expand Down Expand Up @@ -824,10 +807,10 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
if (!hd->align)
hd->align = hd->table_type == TYPE_NONE ? 1 : 512;

if (hd->extended_partition > 4) {
if (hd->extended_partition_index > 4) {
image_error(image, "invalid extended partition index (%i). must be "
"inferior or equal to 4 (0 for automatic)\n",
hd->extended_partition);
hd->extended_partition_index);
return -EINVAL;
}

Expand All @@ -836,21 +819,25 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
"multiple of 1 sector (512 bytes)\n", hd->align);
return -EINVAL;
}
if (hd->table_type == TYPE_MBR && hd->extended_partition)
mbr_entries = hd->extended_partition;
if (hd->table_type == TYPE_MBR && hd->extended_partition_index)
mbr_entries = hd->extended_partition_index;

has_extended = hd->extended_partition_index > 0;

list_for_each_entry(part, &image->partitions, list) {
if (hd->table_type == TYPE_NONE)
part->in_partition_table = false;
if (part->in_partition_table)
++partition_table_entries;
if (hd->table_type == TYPE_MBR && part->in_partition_table) {
if (!hd->extended_partition && partition_table_entries > 4) {
hd->extended_partition = mbr_entries = 4;
if (!hd->extended_partition_index && partition_table_entries > 4) {
hd->extended_partition_index = mbr_entries = 4;
has_extended = true;
}
if (part->forced_primary) {
++forced_primary_entries;
++mbr_entries;
if (partition_table_entries <= hd->extended_partition) {
if (partition_table_entries <= hd->extended_partition_index) {
image_error(image, "partition %s: forced-primary can only be used for "
"partitions following the extended partition\n",
part->name);
Expand All @@ -866,7 +853,6 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
image_error(image, "too many primary partitions\n");
return -EINVAL;
}
image_debug(image, "mbr_entries %d\n", mbr_entries);
}
if (!part->align)
part->align = (part->in_partition_table || hd->table_type == TYPE_NONE) ? hd->align : 1;
Expand All @@ -876,7 +862,6 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
part->align, part->name, hd->align);
}
}
has_extended = hd->extended_partition > 0;

if (hd->disk_uuid) {
if (!(hd->table_type & TYPE_GPT)) {
Expand Down Expand Up @@ -997,12 +982,12 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
if (part->partition_type)
++hybrid_entries;
}
/* reserve space for extended boot record if necessary */
if (part->in_partition_table)
++partition_table_entries;
part->extended = !part->forced_primary && has_extended && part->in_partition_table &&
(partition_table_entries >= hd->extended_partition);
if (part->extended) {
part->logical = !part->forced_primary && has_extended && part->in_partition_table &&
(partition_table_entries >= hd->extended_partition_index);
if (part->logical) {
/* reserve space for extended boot record */
now += hd->align;
now = roundup(now, part->align);
}
Expand All @@ -1017,8 +1002,6 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
if (!part->offset && (part->in_partition_table || hd->table_type == TYPE_NONE)) {
part->offset = roundup(now, part->align);
}
if (part->extended && !hd->extended_lba)
hd->extended_lba = part->offset - hd->align;

if (part->offset % part->align) {
image_error(image, "part %s offset (%lld) must be a"
Expand Down Expand Up @@ -1066,7 +1049,7 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
part->name);
return -EINVAL;
}
if (!part->extended) {
if (!part->logical) {
int ret = check_overlap(image, part);
if (ret)
return ret;
Expand All @@ -1090,11 +1073,21 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
hd->file_size = part->offset + child->size;
}
}
else if (part->extended)
else if (part->logical)
hd->file_size = part->offset - hd->align + 512;

if (part->extended) {
hd->extended_size = part->offset + part->size - hd->extended_lba;
if (has_extended && hd->extended_partition_index == partition_table_entries) {
struct partition *p = fake_partition("[Extended]", now - hd->align - part->size,
0);
p->in_partition_table = true;
p->partition_type = PARTITION_TYPE_EXTENDED;

hd->extended_partition = p;
list_add_tail(&p->list, &part->list);
}

if (part->logical) {
hd->extended_partition->size = now - hd->extended_partition->offset;
}
}

Expand Down

0 comments on commit b8a276e

Please sign in to comment.