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

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