]> git.pld-linux.org Git - packages/parted.git/blob - 0031-Use-BLKSSZGET-to-get-device-sector-size-in-_device_p.patch
- rel 4; tons of patches from FC
[packages/parted.git] / 0031-Use-BLKSSZGET-to-get-device-sector-size-in-_device_p.patch
1 From 61dd3d4c5eb782eb43caa95342e63727db3f8281 Mon Sep 17 00:00:00 2001
2 From: David Cantrell <dcantrell@redhat.com>
3 Date: Thu, 17 Mar 2016 09:24:55 -0400
4 Subject: [PATCH] Use BLKSSZGET to get device sector size in
5  _device_probe_geometry()
6
7 Seen on certain newer devices (such as >32G SDHC memory cards), the
8 HDIO_GETGEO ioctl does not return useful information.  The libparted
9 code records hardware and bios reported geometry information, but all of
10 that is largely unusable these days.  The information is used in the
11 PedConstraint code for aligning partitions.  The sector count is most
12 useful.  Rather than only trying HDIO_GETGIO, first initialize the
13 bios_geom fields to 0 and then use BLKSSZGET to capture the sector size.
14 If that fails, try HDIO_GETGEO.  And if that fails, raise a warning and
15 fall back on the library's default sector size macro.
16
17 This problem showed up on Raspberry Pi devices where users were
18 attempting to grow a partition to fill the SDHC card.  Using the
19 optimal_aligned_constraint returned invalid geometry information
20 (98703359 instead of 124735488 sectors).  The issue was reported here:
21
22     https://github.com/fedberry/fedberry/issues/8
23
24 And to the pyparted project:
25
26     https://github.com/rhinstaller/pyparted/issues/25
27
28 I've applied this patch locally to parted, rebuilt, and reinstalled it
29 and it is working correctly for the problem SDHC cards.
30
31 Signed-off-by: Brian C. Lane <bcl@redhat.com>
32 ---
33  libparted/arch/linux.c | 40 +++++++++++++++++++++++++---------------
34  1 file changed, 25 insertions(+), 15 deletions(-)
35
36 diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
37 index 1198f52..326b956 100644
38 --- a/libparted/arch/linux.c
39 +++ b/libparted/arch/linux.c
40 @@ -852,6 +852,7 @@ _device_probe_geometry (PedDevice* dev)
41          LinuxSpecific*          arch_specific = LINUX_SPECIFIC (dev);
42          struct stat             dev_stat;
43          struct hd_geometry      geometry;
44 +        int                     sector_size = 0;
45  
46          if (!_device_stat (dev, &dev_stat))
47                  return 0;
48 @@ -863,26 +864,35 @@ _device_probe_geometry (PedDevice* dev)
49          if (!dev->length)
50                  return 0;
51  
52 -        /* The GETGEO ioctl is no longer useful (as of linux 2.6.x).  We could
53 -         * still use it in 2.4.x, but this is contentious.  Perhaps we should
54 -         * move to EDD. */
55 -        dev->bios_geom.sectors = 63;
56 -        dev->bios_geom.heads = 255;
57 -        dev->bios_geom.cylinders
58 -                = dev->length / (63 * 255);
59 +        /* initialize the bios_geom values to something */
60 +        dev->bios_geom.sectors = 0;
61 +        dev->bios_geom.heads = 0;
62 +        dev->bios_geom.cylinders = 0;
63  
64 -        /* FIXME: what should we put here?  (TODO: discuss on linux-kernel) */
65 -        if (!ioctl (arch_specific->fd, HDIO_GETGEO, &geometry)
66 +        if (!ioctl (arch_specific->fd, BLKSSZGET, &sector_size)) {
67 +                /* get the sector count first */
68 +                dev->bios_geom.sectors = 1 + (sector_size / PED_SECTOR_SIZE_DEFAULT);
69 +                dev->bios_geom.heads = 255;
70 +        } else if (!ioctl (arch_specific->fd, HDIO_GETGEO, &geometry)
71                          && geometry.sectors && geometry.heads) {
72 -                dev->hw_geom.sectors = geometry.sectors;
73 -                dev->hw_geom.heads = geometry.heads;
74 -                dev->hw_geom.cylinders
75 -                        = dev->length / (dev->hw_geom.heads
76 -                                         * dev->hw_geom.sectors);
77 +                /* if BLKSSZGET failed, try the deprecated HDIO_GETGEO */
78 +                dev->bios_geom.sectors = geometry.sectors;
79 +                dev->bios_geom.heads = geometry.heads;
80          } else {
81 -                dev->hw_geom = dev->bios_geom;
82 +                ped_exception_throw (
83 +                        PED_EXCEPTION_WARNING,
84 +                        PED_EXCEPTION_OK,
85 +                        _("Could not determine sector size for %s: %s.\n"
86 +                          "Using the default sector size (%lld)."),
87 +                        dev->path, strerror (errno), PED_SECTOR_SIZE_DEFAULT);
88 +                dev->bios_geom.sectors = 2;
89 +                dev->bios_geom.heads = 255;
90          }
91  
92 +        dev->bios_geom.cylinders
93 +                = dev->length / (dev->bios_geom.heads
94 +                                 * dev->bios_geom.sectors);
95 +        dev->hw_geom = dev->bios_geom;
96          return 1;
97  }
98  
99 -- 
100 2.5.0
101
This page took 0.065123 seconds and 3 git commands to generate.