[PATCH] linux: use libblkid to determine ->phys_sector_size

Jim Meyering meyering at redhat.com
Thu Oct 15 19:29:36 UTC 2009


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.
---
 configure.ac           |   12 +++++++++
 libparted/Makefile.am  |    1 +
 libparted/arch/linux.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++
 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;
--
1.6.5.1.258.g5b20



More information about the parted-devel mailing list