- Use BLKSSZGET to get device sector size in _device_probe_geometry()

This commit is contained in:
Brian C. Lane 2016-03-29 15:10:13 -07:00
parent 4d35fa8c43
commit 3c4e97cf6e
2 changed files with 106 additions and 2 deletions

View File

@ -0,0 +1,101 @@
From 61dd3d4c5eb782eb43caa95342e63727db3f8281 Mon Sep 17 00:00:00 2001
From: David Cantrell <dcantrell@redhat.com>
Date: Thu, 17 Mar 2016 09:24:55 -0400
Subject: [PATCH] Use BLKSSZGET to get device sector size in
_device_probe_geometry()
Seen on certain newer devices (such as >32G SDHC memory cards), the
HDIO_GETGEO ioctl does not return useful information. The libparted
code records hardware and bios reported geometry information, but all of
that is largely unusable these days. The information is used in the
PedConstraint code for aligning partitions. The sector count is most
useful. Rather than only trying HDIO_GETGIO, first initialize the
bios_geom fields to 0 and then use BLKSSZGET to capture the sector size.
If that fails, try HDIO_GETGEO. And if that fails, raise a warning and
fall back on the library's default sector size macro.
This problem showed up on Raspberry Pi devices where users were
attempting to grow a partition to fill the SDHC card. Using the
optimal_aligned_constraint returned invalid geometry information
(98703359 instead of 124735488 sectors). The issue was reported here:
https://github.com/fedberry/fedberry/issues/8
And to the pyparted project:
https://github.com/rhinstaller/pyparted/issues/25
I've applied this patch locally to parted, rebuilt, and reinstalled it
and it is working correctly for the problem SDHC cards.
Signed-off-by: Brian C. Lane <bcl@redhat.com>
---
libparted/arch/linux.c | 40 +++++++++++++++++++++++++---------------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 1198f52..326b956 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -852,6 +852,7 @@ _device_probe_geometry (PedDevice* dev)
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
struct stat dev_stat;
struct hd_geometry geometry;
+ int sector_size = 0;
if (!_device_stat (dev, &dev_stat))
return 0;
@@ -863,26 +864,35 @@ _device_probe_geometry (PedDevice* dev)
if (!dev->length)
return 0;
- /* The GETGEO ioctl is no longer useful (as of linux 2.6.x). We could
- * still use it in 2.4.x, but this is contentious. Perhaps we should
- * move to EDD. */
- dev->bios_geom.sectors = 63;
- dev->bios_geom.heads = 255;
- dev->bios_geom.cylinders
- = dev->length / (63 * 255);
+ /* initialize the bios_geom values to something */
+ dev->bios_geom.sectors = 0;
+ dev->bios_geom.heads = 0;
+ dev->bios_geom.cylinders = 0;
- /* FIXME: what should we put here? (TODO: discuss on linux-kernel) */
- if (!ioctl (arch_specific->fd, HDIO_GETGEO, &geometry)
+ if (!ioctl (arch_specific->fd, BLKSSZGET, &sector_size)) {
+ /* get the sector count first */
+ dev->bios_geom.sectors = 1 + (sector_size / PED_SECTOR_SIZE_DEFAULT);
+ dev->bios_geom.heads = 255;
+ } else if (!ioctl (arch_specific->fd, HDIO_GETGEO, &geometry)
&& geometry.sectors && geometry.heads) {
- dev->hw_geom.sectors = geometry.sectors;
- dev->hw_geom.heads = geometry.heads;
- dev->hw_geom.cylinders
- = dev->length / (dev->hw_geom.heads
- * dev->hw_geom.sectors);
+ /* if BLKSSZGET failed, try the deprecated HDIO_GETGEO */
+ dev->bios_geom.sectors = geometry.sectors;
+ dev->bios_geom.heads = geometry.heads;
} else {
- dev->hw_geom = dev->bios_geom;
+ ped_exception_throw (
+ PED_EXCEPTION_WARNING,
+ PED_EXCEPTION_OK,
+ _("Could not determine sector size for %s: %s.\n"
+ "Using the default sector size (%lld)."),
+ dev->path, strerror (errno), PED_SECTOR_SIZE_DEFAULT);
+ dev->bios_geom.sectors = 2;
+ dev->bios_geom.heads = 255;
}
+ dev->bios_geom.cylinders
+ = dev->length / (dev->bios_geom.heads
+ * dev->bios_geom.sectors);
+ dev->hw_geom = dev->bios_geom;
return 1;
}
--
2.5.0

View File

@ -4,7 +4,7 @@
Summary: The GNU disk partition manipulation program
Name: parted
Version: 3.2
Release: 17%{?dist}
Release: 18%{?dist}
License: GPLv3+
Group: Applications/System
URL: http://www.gnu.org/software/parted
@ -44,7 +44,7 @@ Patch0027: 0027-tests-Add-wait-to-t9042-1257415.patch
Patch0028: 0028-tests-Fix-t1700-failing-on-a-host-with-a-4k-xfs-file.patch
Patch0029: 0029-lib-fs-resize-Prevent-crash-resizing-FAT-with-very-d.patch
Patch0030: 0030-tests-t3000-resize-fs.sh-Add-very-deep-directory.patch
Patch0031: 0031-Use-BLKSSZGET-to-get-device-sector-size-in-_device_p.patch
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: e2fsprogs-devel
@ -181,6 +181,9 @@ fi
%changelog
* Tue Mar 29 2016 Brian C. Lane <bcl@redhat.com> 3.2-18
- Use BLKSSZGET to get device sector size in _device_probe_geometry()
* Mon Mar 07 2016 Brian C. Lane <bcl@redhat.com> 3.2-17
- lib-fs-resize: Prevent crash resizing FAT with very deep directories
- Add libparted/fs/.libs/ to LD_LIBRARY_PATH during make check