libfdisk: (dos) follow explicit sizes

* this patch add to dos driver support for fdisk_partition->size_explicit
  to avoid unexpected last sector alignment for sizes explicitly specified
  in sectors

* add support for small "first LBA", the current default is to use
  1MiB offset for the first partition and for each EBR. This is not
  backwardly compatible and it makes impossible to apply sfdisk
  scripts/dumps from old systems, because original offset can be
  smaller than 2048 sectors (old sfdisk default is 1 sector).

  The solution is on the fly to detect this situation and change
  fdisk_context->first_lba to 1 sector. Nasty.

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2014-10-09 12:10:36 +02:00
parent 18b266cea3
commit bcdeacd796
1 changed files with 26 additions and 5 deletions

View File

@ -970,8 +970,13 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
if (n < 4) {
if (cxt->parent && fdisk_is_label(cxt->parent, GPT))
start = 1; /* Bad boy modifies hybrid MBR */
else
else {
if (cxt->script && pa && pa->start && pa->start < cxt->first_lba
&& pa->start >= 1)
fdisk_set_first_lba(cxt, 1);
start = cxt->first_lba;
}
if (fdisk_use_cylinders(cxt) || !cxt->total_sectors)
limit = cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders - 1;
@ -988,8 +993,14 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
}
} else {
assert(ext_pe);
start = l->ext_offset + cxt->first_lba;
limit = get_abs_partition_end(ext_pe);
if (cxt->script && pa && pa->start && pa->start >= l->ext_offset
&& pa->start < l->ext_offset + cxt->first_lba)
fdisk_set_first_lba(cxt, 1);
start = l->ext_offset + cxt->first_lba;
}
if (fdisk_use_cylinders(cxt))
for (i = 0; i < cxt->label->nparts_max; i++) {
@ -1006,6 +1017,13 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
temp = start;
dflt = start = get_unused_start(cxt, n, start, first, last);
if (n >= 4 && pa && pa->start && cxt->script
&& cxt->first_lba > 1
&& temp == start - cxt->first_lba) {
fdisk_set_first_lba(cxt, 1);
start = pa->start;
}
/* the default sector should be aligned and unused */
do {
aligned = fdisk_align_lba_in_range(cxt, dflt, dflt, limit);
@ -1074,8 +1092,8 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
else if (pa && pa->end_follow_default)
stop = limit;
else if (pa && pa->size) {
stop = start + pa->size;
isrel = 1;
stop = start + pa->size - 1;
isrel = pa->size_explicit ? 0 : 1;
} else {
/* ask user by dialog */
struct fdisk_ask *ask = fdisk_new_ask();
@ -1109,9 +1127,12 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
stop = stop * fdisk_get_units_per_sector(cxt) - 1;
if (stop >limit)
stop = limit;
}
} else
stop -= 1;
}
DBG(LABEL, ul_debug("DOS: raw stop: %ju", (uintmax_t) stop));
if (stop > limit)
stop = limit;