From: Karel Zak Date: Tue, 11 Jul 2017 10:25:02 +0000 (+0200) Subject: libfdisk: (dos) cleanup template based partitioning X-Git-Tag: v2.30.1~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=df994aca9ef463c811c4f8ce986d88c430023cf7;p=thirdparty%2Futil-linux.git libfdisk: (dos) cleanup template based partitioning Signed-off-by: Karel Zak --- diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index 588635f00d..da21b0956a 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -1561,59 +1561,67 @@ static int dos_add_partition(struct fdisk_context *cxt, * partition template (@pa) based partitioning */ - /* pa specifies start within extended partition, add logical */ + /* A) template specifies start within extended partition; add logical */ if (pa && fdisk_partition_has_start(pa) && ext_pe && pa->start >= l->ext_offset && pa->start <= get_abs_partition_end(ext_pe)) { - DBG(LABEL, ul_debug("DOS: pa template %p: add logical", pa)); + DBG(LABEL, ul_debug("DOS: pa template %p: add logical (by offset)", pa)); + + if (fdisk_partition_has_partno(pa) && fdisk_partition_get_partno(pa) < 4) { + DBG(LABEL, ul_debug("DOS: pa template specifies partno<4 for logical partition")); + return -EINVAL; + } rc = add_logical(cxt, pa, &res); goto done; - /* pa specifies that extended partition is wanted */ - } else if (pa && pa->type && IS_EXTENDED(pa->type->code)) { - DBG(LABEL, ul_debug("DOS: pa template %p: add extended", pa)); - if (l->ext_offset) { - fdisk_warnx(cxt, _("Extended partition already exists.")); + /* B) template specifies start out of extended partition; add primary */ + } else if (pa && fdisk_partition_has_start(pa) && ext_pe) { + DBG(LABEL, ul_debug("DOS: pa template %p: add primary (by offset)", pa)); + + if (fdisk_partition_has_partno(pa) && fdisk_partition_get_partno(pa) >= 4) { + DBG(LABEL, ul_debug("DOS: pa template specifies partno>=4 for primary partition")); return -EINVAL; } - rc = get_partition_unused_primary(cxt, pa, &res); - if (rc == 0) { - rc = add_partition(cxt, res, pa); - goto done; + if (pa->type && IS_EXTENDED(pa->type->code)) { + fdisk_warnx(cxt, _("Extended partition already exists.")); + return -EINVAL; } - - /* pa specifies start, but outside extended partition */ - } else if (pa && fdisk_partition_has_start(pa) && l->ext_offset) { - DBG(LABEL, ul_debug("DOS: pa template %p: add primary", pa)); rc = get_partition_unused_primary(cxt, pa, &res); if (rc == 0) rc = add_partition(cxt, res, pa); goto done; - /* pa follows default, but partno < 4, it means primary partition */ - } else if (pa && fdisk_partition_start_is_default(pa) + /* C) template specifies start (or default), partno < 4; add primary */ + } else if (pa && (fdisk_partition_start_is_default(pa) || fdisk_partition_has_start(pa)) && fdisk_partition_has_partno(pa) && pa->partno < 4) { - DBG(LABEL, ul_debug("DOS: pa template %p: add primary (partno < 4)", pa)); + DBG(LABEL, ul_debug("DOS: pa template %p: add primary (by partno)", pa)); + + if (ext_pe && pa->type && IS_EXTENDED(pa->type->code)) { + fdisk_warnx(cxt, _("Extended partition already exists.")); + return -EINVAL; + } rc = get_partition_unused_primary(cxt, pa, &res); if (rc == 0) rc = add_partition(cxt, res, pa); goto done; - /* pa follows default, but partno >= 4, it means logical partition */ + /* D) template specifies default start, partno >= 4; add logical */ } else if (pa && fdisk_partition_start_is_default(pa) - && ext_pe && fdisk_partition_has_partno(pa) && pa->partno >= 4) { - DBG(LABEL, ul_debug("DOS: pa template %p: add logical (partno >= 4)", pa)); + DBG(LABEL, ul_debug("DOS: pa template %p: add logical (by partno)", pa)); + + if (!ext_pe) { + fdisk_warnx(cxt, _("Extended partition does not exists. Failed to add logical partition")); + return -EINVAL; + } rc = add_logical(cxt, pa, &res); goto done; } - /* - * dialog driven partitioning (it does not mean that @pa template is - * completely ignored!) - */ + DBG(LABEL, ul_debug("DOS: dialog driven partitioning")); + /* Note @pa may be still used for things like partition type, etc */ /* check if there is space for primary partition */ grain = cxt->grain > cxt->sector_size ? cxt->grain / cxt->sector_size : 1; diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c index 95baea0c21..6d996e7d7b 100644 --- a/libfdisk/src/partition.c +++ b/libfdisk/src/partition.c @@ -1337,6 +1337,18 @@ int fdisk_partition_has_wipe(struct fdisk_context *cxt, struct fdisk_partition * * If @pa is not specified or any @pa item is missing the libfdisk will ask by * fdisk_ask_ API. * + * The @pa template is is important for non-interactive partitioning, + * especially for MBR where is necessary to differentiate between + * primary/logical; this is done by start offset or/and partno. + * The rules for MBR: + * + * A) template specifies start within extended partition: add logical + * B) template specifies start out of extended partition: add primary + * C) template specifies start (or default), partno < 4: add primary + * D) template specifies default start, partno >= 4: add logical + * + * otherwise MBR driver uses Ask-API to get missing information. + * * Adds a new partition to disklabel. * * Returns: 0 on success, <0 on error.