diff options
author | Karel Zak | 2014-10-09 12:10:36 +0200 |
---|---|---|
committer | Karel Zak | 2014-10-09 12:10:36 +0200 |
commit | bcdeacd7962a84f59aa805bd2b4ea3a213ff86d4 (patch) | |
tree | e456cb78e451f4d1469c71a9e40730216f1e3411 /libfdisk/src/dos.c | |
parent | libfdisk: (gpt) follow explicit size, fiz size+1 buf (diff) | |
download | kernel-qcow2-util-linux-bcdeacd7962a84f59aa805bd2b4ea3a213ff86d4.tar.gz kernel-qcow2-util-linux-bcdeacd7962a84f59aa805bd2b4ea3a213ff86d4.tar.xz kernel-qcow2-util-linux-bcdeacd7962a84f59aa805bd2b4ea3a213ff86d4.zip |
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>
Diffstat (limited to 'libfdisk/src/dos.c')
-rw-r--r-- | libfdisk/src/dos.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index 6c30df743..e350d08de 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -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; |