libfdisk: (gpt) initialize last_lba, cleanup pa->{start,size} usage

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2014-01-29 14:20:11 +01:00
parent ef7b2f1c88
commit 1240f549d8
1 changed files with 69 additions and 20 deletions

View File

@ -467,6 +467,22 @@ static struct gpt_header *gpt_copy_header(struct fdisk_context *cxt,
return res;
}
static void count_first_last_lba(struct fdisk_context *cxt,
uint64_t *first, uint64_t *last)
{
uint64_t esz = 0;
assert(cxt);
esz = sizeof(struct gpt_entry) * GPT_NPARTITIONS / cxt->sector_size;
*last = cxt->total_sectors - 2 - esz;
*first = esz + 2;
if (*first < cxt->first_lba && cxt->first_lba < *last)
/* Align according to topology */
*first = cxt->first_lba;
}
/*
* Builds a clean new GPT header (currently under revision 1.0).
*
@ -478,13 +494,11 @@ static struct gpt_header *gpt_copy_header(struct fdisk_context *cxt,
static int gpt_mknew_header(struct fdisk_context *cxt,
struct gpt_header *header, uint64_t lba)
{
uint64_t esz = 0, first, last;
uint64_t first, last;
if (!cxt || !header)
return -ENOSYS;
esz = sizeof(struct gpt_entry) * GPT_NPARTITIONS / cxt->sector_size;
header->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
header->revision = cpu_to_le32(GPT_HEADER_REVISION_V1_00);
header->size = cpu_to_le32(sizeof(struct gpt_header));
@ -496,13 +510,7 @@ static int gpt_mknew_header(struct fdisk_context *cxt,
header->npartition_entries = cpu_to_le32(GPT_NPARTITIONS);
header->sizeof_partition_entry = cpu_to_le32(sizeof(struct gpt_entry));
last = cxt->total_sectors - 2 - esz;
first = esz + 2;
if (first < cxt->first_lba && cxt->first_lba < last)
/* Align according to topology */
first = cxt->first_lba;
count_first_last_lba(cxt, &first, &last);
header->first_usable_lba = cpu_to_le64(first);
header->last_usable_lba = cpu_to_le64(last);
@ -1680,6 +1688,9 @@ static int gpt_create_new_partition(struct fdisk_context *cxt,
assert(cxt->label);
assert(fdisk_is_disklabel(cxt, GPT));
DBG(LABEL, dbgprint("GPT new partition: partno=%zu, start=%ju, end=%ju",
partnum, fsect, lsect));
gpt = self_label(cxt);
if (fsect > lsect || partnum >= cxt->label->nparts_max)
@ -1735,9 +1746,10 @@ static int gpt_add_partition(
ents = gpt->ents;
rc = fdisk_partition_next_partno(pa, cxt, &partnum);
if (rc)
if (rc) {
DBG(LABEL, dbgprint("GPT failed to get next partno"));
return rc;
}
if (!partition_unused(&ents[partnum])) {
fdisk_warnx(cxt, _("Partition %zu is already defined. "
"Delete it before re-adding it."), partnum +1);
@ -1804,15 +1816,17 @@ static int gpt_add_partition(
}
}
/* Last sector */
dflt_l = find_last_free(pheader, ents, user_f);
if (pa && pa->size) {
if (pa->size + user_f > dflt_l)
return -ERANGE;
user_l = user_f + pa->size;
user_l = fdisk_align_lba_in_range(cxt, user_l, user_f, dflt_l) - 1;
if (user_l + (cxt->grain / cxt->sector_size) > dflt_l)
user_l = dflt_l; /* no space for anything useful, use all space */
} else if (pa && pa->end_follow_default) {
user_l = dflt_l;
} else {
@ -1835,17 +1849,20 @@ static int gpt_add_partition(
goto done;
user_l = fdisk_ask_number_get_result(ask);
if (fdisk_ask_number_is_relative(ask))
if (fdisk_ask_number_is_relative(ask)) {
user_l = fdisk_align_lba_in_range(cxt, user_l, user_f, dflt_l) - 1;
if (user_l > user_f && user_l <= disk_l)
if (user_l + (cxt->grain / cxt->sector_size) > dflt_l)
user_l = dflt_l; /* no space for anything useful, use all space */
} if (user_l > user_f && user_l <= disk_l)
break;
}
}
if (gpt_create_new_partition(cxt, partnum,
user_f, user_l, &typeid, ents) != 0)
if ((rc = gpt_create_new_partition(cxt, partnum,
user_f, user_l, &typeid, ents) != 0)) {
fdisk_warnx(cxt, _("Could not create partition %ju"), partnum + 1);
else {
goto done;
} else {
struct fdisk_parttype *t;
cxt->label->nparts_cur++;
@ -2220,6 +2237,36 @@ static int gpt_toggle_partition_flag(
return 0;
}
static int gpt_reset_alignment(struct fdisk_context *cxt)
{
struct fdisk_gpt_label *gpt;
struct gpt_header *h;
assert(cxt);
assert(cxt->label);
assert(fdisk_is_disklabel(cxt, GPT));
gpt = self_label(cxt);
h = gpt ? gpt->pheader : NULL;
if (h) {
/* always follow existing table */
cxt->first_lba = h->first_usable_lba;
cxt->last_lba = h->last_usable_lba;
} else {
/* estimate ranges for GPT */
uint64_t first, last;
count_first_last_lba(cxt, &first, &last);
if (cxt->first_lba < first)
cxt->first_lba = first;
if (cxt->last_lba > last)
cxt->last_lba = last;
}
return 0;
}
/*
* Deinitialize fdisk-specific variables
*/
@ -2259,7 +2306,9 @@ static const struct fdisk_label_operations gpt_operations =
.part_set_type = gpt_set_partition_type,
.part_toggle_flag = gpt_toggle_partition_flag,
.deinit = gpt_deinit
.deinit = gpt_deinit,
.reset_alignment = gpt_reset_alignment
};
static const struct fdisk_column gpt_columns[] =