]>
Commit | Line | Data |
---|---|---|
c886eb9d AM |
1 | From e4bf9b823452c0b98b394b8abcc67f887b6991b3 Mon Sep 17 00:00:00 2001 |
2 | From: Petr Uzel <petr.uzel@suse.cz> | |
3 | Date: Thu, 21 Jul 2016 16:46:46 +0200 | |
4 | Subject: [PATCH 44/53] libparted: only IEC units are treated as exact | |
5 | ||
6 | If the user specifies start/end of the partition as a unit, | |
7 | whose size happens to be power of two, we treat that as | |
8 | exact address with exact placement. | |
9 | ||
10 | Recently, commit 01900e056ec25083 added an exception for | |
11 | percent units. | |
12 | ||
13 | This logic however can fail also for cylinders, e.g. on DASD FBA disks, | |
14 | which report CHS=(*, 128, 16) geometry, hence once cylinder is 1 MiB. | |
15 | With cylinders as units, exact placement is not what the user wants. | |
16 | ||
17 | Instead of adding cylinders to the blacklist, let's instead | |
18 | whitelist units which should trigger exact placement. | |
19 | ||
20 | * libparted/unit.c (is_power_of_2): Remove now unused function. | |
21 | (ped_unit_parse_custom): Specify which units trigger exact placement. | |
22 | * NEWS (Bug Fixes): Mention this. | |
23 | ||
24 | (cherry picked from commit f4f38082fc4dbf0c28ccc7613c672fe279d3032e) | |
25 | --- | |
26 | libparted/unit.c | 33 +++++++++++++++++---------------- | |
27 | 1 file changed, 17 insertions(+), 16 deletions(-) | |
28 | ||
29 | diff --git a/libparted/unit.c b/libparted/unit.c | |
30 | index dddb5db..e47e868 100644 | |
31 | --- a/libparted/unit.c | |
32 | +++ b/libparted/unit.c | |
33 | @@ -481,12 +481,6 @@ parse_unit_suffix (const char* suffix, PedUnit suggested_unit) | |
34 | return suggested_unit; | |
35 | } | |
36 | ||
37 | -static bool | |
38 | -is_power_of_2 (long long n) | |
39 | -{ | |
40 | - return (n & (n - 1)) == 0; | |
41 | -} | |
42 | - | |
43 | /** | |
44 | * If \p str contains a valid description of a location on \p dev, then | |
45 | * \p *sector is modified to describe the location and a geometry is created | |
46 | @@ -540,16 +534,23 @@ ped_unit_parse_custom (const char* str, const PedDevice* dev, PedUnit unit, | |
47 | } | |
48 | ||
49 | unit_size = ped_unit_get_size (dev, unit); | |
50 | - radius = (ped_div_round_up (unit_size, dev->sector_size) / 2) - 1; | |
51 | - if (radius < 0) | |
52 | - radius = 0; | |
53 | - /* If the user specifies units in a power of 2, e.g., 4MiB, as in | |
54 | - parted -s -- $dev mklabel gpt mkpart P-NAME 4MiB -34s | |
55 | - do not use 4MiB as the range. Rather, presume that they | |
56 | - are specifying precisely the starting or ending number, | |
57 | - and treat "4MiB" just as we would treat "4194304B". */ | |
58 | - if (is_power_of_2 (unit_size) && unit != PED_UNIT_PERCENT) | |
59 | - radius = 0; | |
60 | + switch (unit) { | |
61 | + /* If the user specifies the address using IEC units e.g., 4MiB, as in | |
62 | + parted -s -- $dev mklabel gpt mkpart P-NAME 4MiB -34s | |
63 | + do not use size of the unit as the range. Rather, presume that they | |
64 | + are specifying precisely the starting or ending number, | |
65 | + and treat "4MiB" just as we would treat "4194304B". */ | |
66 | + case PED_UNIT_KIBIBYTE: | |
67 | + case PED_UNIT_MEBIBYTE: | |
68 | + case PED_UNIT_GIBIBYTE: | |
69 | + case PED_UNIT_TEBIBYTE: | |
70 | + radius = 0; | |
71 | + break; | |
72 | + default: | |
73 | + radius = (ped_div_round_up (unit_size, dev->sector_size) / 2) - 1; | |
74 | + if (radius < 0) | |
75 | + radius = 0; | |
76 | + } | |
77 | ||
78 | *sector = num * unit_size / dev->sector_size; | |
79 | /* negative numbers count from the end */ | |
80 | -- | |
81 | 2.7.4 | |
82 |