diff options
-rw-r--r-- | configure.ac | 12 | ||||
-rw-r--r-- | libparted/Makefile.am | 1 | ||||
-rw-r--r-- | 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; |