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

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