summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2009-10-15 21:29:36 +0200
committerJim Meyering <meyering@redhat.com>2009-10-19 14:58:26 +0200
commit979bf88defcd1411c4c0adf5faa3d4b0e27b4ac4 (patch)
tree2a5182db1c12b88542c6380f11439d1e4c6b5894
parentf6859f2fcbcf18a069a0495cbb8bd2baf395e74d (diff)
downloadparted-979bf88defcd1411c4c0adf5faa3d4b0e27b4ac4.tar.gz
linux: use libblkid to determine ->phys_sector_size
Before this change, creating a memory-mapped disk on a fedora-based system running 2.6.31.1-56.fc12.x86_64 using this command: modprobe scsi_debug dev_size_mb=1025 sector_size=4096 and then running "parted -s /dev/sdd mklabel gpt print" would mistakenly print "Sector size (logical/physical): 4096B/512B" The "512B" is what's wrong. It should be "4096B". * configure.ac: Test for a new-enough blkid library. * libparted/Makefile.am (libparted_la_LIBADD): Add $(LIB_BLKID). * libparted/arch/linux.c (get_minimum_io_size): New function. (_device_set_sector_size): Use it.
-rw-r--r--configure.ac12
-rw-r--r--libparted/Makefile.am1
-rw-r--r--libparted/arch/linux.c60
3 files changed, 73 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 0500b5b..af1caee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -603,6 +603,18 @@ HOST=$(hostname)
BUILDINFO="$USER@$HOST, $DATE"
AC_SUBST([BUILDINFO])
+LIB_BLKID=
+AC_SUBST([LIB_BLKID])
+pe_saved_libs=$LIBS
+ AC_SEARCH_LIBS([blkid_probe_get_topology], [blkid],
+ [test "$ac_cv_search_blkid_probe_get_topology" = "none required" \
+ || LIB_BLKID=$ac_cv_search_blkid_probe_get_topology])
+ AC_CHECK_FUNC([blkid_probe_get_topology], [use_blkid=1], [use_blkid=0])
+LIBS=$pe_saved_libs
+AC_DEFINE_UNQUOTED([USE_BLKID], [$use_blkid],
+ [Define if you have sufficient blkid support.])
+AC_CHECK_HEADERS_ONCE([blkid/blkid.h])
+
AC_OUTPUT([
Makefile
lib/Makefile
diff --git a/libparted/Makefile.am b/libparted/Makefile.am
index e5f8542..e77e6e0 100644
--- a/libparted/Makefile.am
+++ b/libparted/Makefile.am
@@ -52,6 +52,7 @@ libparted_la_LIBADD = \
$(DL_LIBS) \
$(DM_LIBS) \
$(SELINUX_LIBS) \
+ $(LIB_BLKID) \
$(INTLLIBS)
EXTRA_DIST = mbr.s
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 094e8d2..e545f0a 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -52,6 +52,10 @@
# define _(String) (String)
#endif /* ENABLE_NLS */
+#if HAVE_BLKID_BLKID_H
+# include <blkid/blkid.h>
+#endif
+
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#ifndef __NR__llseek
@@ -592,6 +596,48 @@ _have_kern26 ()
return have_kern26 = kver >= KERNEL_VERSION (2,6,0) ? 1 : 0;
}
+/* Use libblkid to determine the kernel's idea of the
+ minimum_io_size for the device on which FD is open.
+ Upon success, store that value in *SZ and return 0.
+ Otherwise, don't modify *SZ, set errno and return -1. */
+static int
+get_minimum_io_size (int fd, unsigned long *sz)
+{
+ int ret = -1;
+
+#if USE_BLKID
+ blkid_probe pr = blkid_new_probe ();
+ if (!pr)
+ goto free_and_return;
+
+ int saved_errno;
+ if (blkid_probe_set_device (pr, fd, 0, 0)) {
+ saved_errno = errno;
+ blkid_free_probe (pr);
+ goto free_and_return;
+ }
+
+ blkid_topology tp = blkid_probe_get_topology (pr);
+ if (!tp) {
+ saved_errno = errno;
+ goto free_and_return;
+ }
+
+ *sz = blkid_topology_get_minimum_io_size (tp);
+ ret = 0;
+
+free_and_return:
+
+ blkid_free_probe (pr);
+ if (ret)
+ errno = saved_errno;
+#else
+ errno = ENOSYS;
+#endif
+
+ return ret;
+}
+
static void
_device_set_sector_size (PedDevice* dev)
{
@@ -619,6 +665,20 @@ _device_set_sector_size (PedDevice* dev)
dev->sector_size = (long long)sector_size;
}
+ unsigned long min_io_size;
+ int err = get_minimum_io_size (arch_specific->fd, &min_io_size);
+
+ if (err) {
+ ped_exception_throw (
+ PED_EXCEPTION_WARNING,
+ PED_EXCEPTION_OK,
+ _("Could not determine minimum io size for %s: %s.\n"
+ "Using the default size (%lld)."),
+ dev->path, strerror (errno), PED_SECTOR_SIZE_DEFAULT);
+ min_io_size = PED_SECTOR_SIZE_DEFAULT;
+ }
+ dev->phys_sector_size = min_io_size;
+
/* Return PED_SECTOR_SIZE_DEFAULT for DASDs. */
if (dev->type == PED_DEVICE_DASD) {
dev->sector_size = PED_SECTOR_SIZE_DEFAULT;