summaryrefslogtreecommitdiffstats
path: root/libfdisk/src/dos.c
diff options
context:
space:
mode:
authorKarel Zak2014-10-09 12:10:36 +0200
committerKarel Zak2014-10-09 12:10:36 +0200
commitbcdeacd7962a84f59aa805bd2b4ea3a213ff86d4 (patch)
treee456cb78e451f4d1469c71a9e40730216f1e3411 /libfdisk/src/dos.c
parentlibfdisk: (gpt) follow explicit size, fiz size+1 buf (diff)
downloadkernel-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.c31
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;