diff options
Diffstat (limited to 'debian/patches/upstream/0010-libfdisk-make-scripts-portable-between-different-sec.patch')
-rw-r--r-- | debian/patches/upstream/0010-libfdisk-make-scripts-portable-between-different-sec.patch | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/debian/patches/upstream/0010-libfdisk-make-scripts-portable-between-different-sec.patch b/debian/patches/upstream/0010-libfdisk-make-scripts-portable-between-different-sec.patch new file mode 100644 index 0000000..98039a2 --- /dev/null +++ b/debian/patches/upstream/0010-libfdisk-make-scripts-portable-between-different-sec.patch @@ -0,0 +1,130 @@ +From: Karel Zak <kzak@redhat.com> +Date: Mon, 11 Jul 2022 14:02:30 +0200 +Subject: [PATCH 10/24] libfdisk: make scripts portable between different + sector sizes + +Fixes: https://github.com/util-linux/util-linux/issues/1744 +Signed-off-by: Karel Zak <kzak@redhat.com> +--- + libfdisk/src/script.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 70 insertions(+), 1 deletion(-) + +diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c +index d93b981..b620eda 100644 +--- a/libfdisk/src/script.c ++++ b/libfdisk/src/script.c +@@ -63,6 +63,8 @@ struct fdisk_script { + size_t nlines; + struct fdisk_label *label; + ++ unsigned long sector_size; /* as defined by script */ ++ + unsigned int json : 1, /* JSON output */ + force_label : 1; /* label: <name> specified */ + }; +@@ -806,6 +808,19 @@ static int parse_line_header(struct fdisk_script *dp, char *s) + return -EINVAL; /* unknown label name */ + dp->force_label = 1; + ++ } else if (strcmp(name, "sector-size") == 0) { ++ uint64_t x = 0; ++ ++ if (ul_strtou64(value, &x, 10) != 0) ++ return -EINVAL; ++ if (x > ULONG_MAX || x % 512) ++ return -ERANGE; ++ dp->sector_size = (unsigned long) x; ++ ++ if (dp->cxt && dp->sector_size && dp->cxt->sector_size ++ && dp->sector_size != dp->cxt->sector_size) ++ fdisk_warnx(dp->cxt, _("The script and device sector size differ; the sizes will be recalculated to match the device.")); ++ + } else if (strcmp(name, "unit") == 0) { + if (strcmp(value, "sectors") != 0) + return -EINVAL; /* only "sectors" supported */ +@@ -966,6 +981,27 @@ static int skip_optional_sign(char **str) + return 0; + } + ++static int recount_script2device_sectors(struct fdisk_script *dp, uint64_t *num) ++{ ++ if (!dp->cxt || ++ !dp->sector_size || ++ !dp->cxt->sector_size) ++ return 0; ++ ++ if (dp->sector_size > dp->cxt->sector_size) ++ *num *= (dp->sector_size / dp->cxt->sector_size); ++ ++ else if (dp->sector_size < dp->cxt->sector_size) { ++ uint64_t x = dp->cxt->sector_size / dp->sector_size; ++ ++ if (*num % x) ++ return -EINVAL; ++ *num /= x; ++ } ++ ++ return 0; ++} ++ + static int parse_start_value(struct fdisk_script *dp, struct fdisk_partition *pa, char **str) + { + char *tk; +@@ -997,7 +1033,14 @@ static int parse_start_value(struct fdisk_script *dp, struct fdisk_partition *pa + goto done; + } + num /= dp->cxt->sector_size; ++ } else { ++ rc = recount_script2device_sectors(dp, &num); ++ if (rc) { ++ fdisk_warnx(dp->cxt, _("Can't recalculate partition start to the device sectors")); ++ goto done; ++ } + } ++ + fdisk_partition_set_start(pa, num); + + pa->movestart = sign == '-' ? FDISK_MOVE_DOWN : +@@ -1046,8 +1089,15 @@ static int parse_size_value(struct fdisk_script *dp, struct fdisk_partition *pa, + goto done; + } + num /= dp->cxt->sector_size; +- } else /* specified as number of sectors */ ++ } else { ++ /* specified as number of sectors */ + fdisk_partition_size_explicit(pa, 1); ++ rc = recount_script2device_sectors(dp, &num); ++ if (rc) { ++ fdisk_warnx(dp->cxt, _("Can't recalculate partition size to the device sectors")); ++ goto done; ++ } ++ } + + fdisk_partition_set_size(pa, num); + pa->resize = sign == '-' ? FDISK_RESIZE_REDUCE : +@@ -1492,6 +1542,25 @@ int fdisk_apply_script_headers(struct fdisk_context *cxt, struct fdisk_script *d + DBG(SCRIPT, ul_debugobj(dp, "applying script headers")); + fdisk_set_script(cxt, dp); + ++ if (dp->sector_size && dp->cxt->sector_size != dp->sector_size) { ++ /* ++ * Ignore last and first LBA if device sector size mismatch ++ * with sector size in script. It would be possible to ++ * recalculate it, but for GPT it will not work in some cases ++ * as these offsets are calculated by relative number of ++ * sectors. It's better to use library defaults than try ++ * to be smart ... ++ */ ++ if (fdisk_script_get_header(dp, "first-lba")) { ++ fdisk_script_set_header(dp, "first-lba", NULL); ++ fdisk_info(dp->cxt, _("Ingnore \"first-lba\" header due to sector size mismatch.")); ++ } ++ if (fdisk_script_get_header(dp, "last-lba")) { ++ fdisk_script_set_header(dp, "last-lba", NULL); ++ fdisk_info(dp->cxt, _("Ingnore \"last-lba\" header due to sector size mismatch.")); ++ } ++ } ++ + str = fdisk_script_get_header(dp, "grain"); + if (str) { + uintmax_t sz; |