OSDN Git Service

linux: use libblkid to determine ->phys_sector_size
authorJim Meyering <meyering@redhat.com>
Thu, 15 Oct 2009 19:29:36 +0000 (21:29 +0200)
committerJim Meyering <meyering@redhat.com>
Mon, 19 Oct 2009 12:58:26 +0000 (14:58 +0200)
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
libparted/Makefile.am
libparted/arch/linux.c

index 0500b5b..af1caee 100644 (file)
@@ -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
index e5f8542..e77e6e0 100644 (file)
@@ -52,6 +52,7 @@ libparted_la_LIBADD = \
   $(DL_LIBS)           \
   $(DM_LIBS)           \
   $(SELINUX_LIBS)      \
+  $(LIB_BLKID)         \
   $(INTLLIBS)
 
 EXTRA_DIST           = mbr.s
index 094e8d2..e545f0a 100644 (file)
 #  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;