Blame SOURCES/0044-libparted-only-IEC-units-are-treated-as-exact.patch

0cb0b9
From e4bf9b823452c0b98b394b8abcc67f887b6991b3 Mon Sep 17 00:00:00 2001
0cb0b9
From: Petr Uzel <petr.uzel@suse.cz>
0cb0b9
Date: Thu, 21 Jul 2016 16:46:46 +0200
0cb0b9
Subject: [PATCH 44/53] libparted: only IEC units are treated as exact
0cb0b9
0cb0b9
If the user specifies start/end of the partition as a unit,
0cb0b9
whose size happens to be power of two, we treat that as
0cb0b9
exact address with exact placement.
0cb0b9
0cb0b9
Recently, commit 01900e056ec25083 added an exception for
0cb0b9
percent units.
0cb0b9
0cb0b9
This logic however can fail also for cylinders, e.g. on DASD FBA disks,
0cb0b9
which report CHS=(*, 128, 16) geometry, hence once cylinder is 1 MiB.
0cb0b9
With cylinders as units, exact placement is not what the user wants.
0cb0b9
0cb0b9
Instead of adding cylinders to the blacklist, let's instead
0cb0b9
whitelist units which should trigger exact placement.
0cb0b9
0cb0b9
* libparted/unit.c (is_power_of_2): Remove now unused function.
0cb0b9
(ped_unit_parse_custom): Specify which units trigger exact placement.
0cb0b9
* NEWS (Bug Fixes): Mention this.
0cb0b9
0cb0b9
(cherry picked from commit f4f38082fc4dbf0c28ccc7613c672fe279d3032e)
0cb0b9
---
0cb0b9
 libparted/unit.c | 33 +++++++++++++++++----------------
0cb0b9
 1 file changed, 17 insertions(+), 16 deletions(-)
0cb0b9
0cb0b9
diff --git a/libparted/unit.c b/libparted/unit.c
0cb0b9
index dddb5db..e47e868 100644
0cb0b9
--- a/libparted/unit.c
0cb0b9
+++ b/libparted/unit.c
0cb0b9
@@ -481,12 +481,6 @@ parse_unit_suffix (const char* suffix, PedUnit suggested_unit)
0cb0b9
 	return suggested_unit;
0cb0b9
 }
0cb0b9
 
0cb0b9
-static bool
0cb0b9
-is_power_of_2 (long long n)
0cb0b9
-{
0cb0b9
-  return (n & (n - 1)) == 0;
0cb0b9
-}
0cb0b9
-
0cb0b9
 /**
0cb0b9
  * If \p str contains a valid description of a location on \p dev, then
0cb0b9
  * \p *sector is modified to describe the location and a geometry is created
0cb0b9
@@ -540,16 +534,23 @@ ped_unit_parse_custom (const char* str, const PedDevice* dev, PedUnit unit,
0cb0b9
         }
0cb0b9
 
0cb0b9
 	unit_size = ped_unit_get_size (dev, unit);
0cb0b9
-	radius = (ped_div_round_up (unit_size, dev->sector_size) / 2) - 1;
0cb0b9
-	if (radius < 0)
0cb0b9
-		radius = 0;
0cb0b9
-	/* If the user specifies units in a power of 2, e.g., 4MiB, as in
0cb0b9
-	       parted -s -- $dev mklabel gpt mkpart P-NAME 4MiB -34s
0cb0b9
-	   do not use 4MiB as the range.  Rather, presume that they
0cb0b9
-	   are specifying precisely the starting or ending number,
0cb0b9
-	   and treat "4MiB" just as we would treat "4194304B".  */
0cb0b9
-	if (is_power_of_2 (unit_size) && unit != PED_UNIT_PERCENT)
0cb0b9
-		radius = 0;
0cb0b9
+	switch (unit) {
0cb0b9
+		/* If the user specifies the address using IEC units e.g., 4MiB, as in
0cb0b9
+		   parted -s -- $dev mklabel gpt mkpart P-NAME 4MiB -34s
0cb0b9
+		   do not use size of the unit as the range.  Rather, presume that they
0cb0b9
+		   are specifying precisely the starting or ending number,
0cb0b9
+		   and treat "4MiB" just as we would treat "4194304B".  */
0cb0b9
+		case PED_UNIT_KIBIBYTE:
0cb0b9
+		case PED_UNIT_MEBIBYTE:
0cb0b9
+		case PED_UNIT_GIBIBYTE:
0cb0b9
+		case PED_UNIT_TEBIBYTE:
0cb0b9
+			radius = 0;
0cb0b9
+			break;
0cb0b9
+		default:
0cb0b9
+			radius = (ped_div_round_up (unit_size, dev->sector_size) / 2) - 1;
0cb0b9
+			if (radius < 0)
0cb0b9
+				radius = 0;
0cb0b9
+	}
0cb0b9
 
0cb0b9
 	*sector = num * unit_size / dev->sector_size;
0cb0b9
 	/* negative numbers count from the end */
0cb0b9
-- 
0cb0b9
2.7.4
0cb0b9