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