From d7a0d860b93484634e35eaadb8ccf5e526420c3d Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Wed, 26 Jul 2017 14:32:21 +0200 Subject: [PATCH] Use getvfs for block size of filesytem if available. --- configure.ac | 2 +- lib/utils_device.c | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 4dbcd6a7..29823fb1 100644 --- a/configure.ac +++ b/configure.ac @@ -37,7 +37,7 @@ PKG_PROG_PKG_CONFIG AC_HEADER_DIRENT AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \ - sys/sysmacros.h ctype.h unistd.h locale.h byteswap.h endian.h) + sys/sysmacros.h sys/statvfs.h ctype.h unistd.h locale.h byteswap.h endian.h) AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])]) AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])]) diff --git a/lib/utils_device.c b/lib/utils_device.c index ea83311c..b62d5875 100644 --- a/lib/utils_device.c +++ b/lib/utils_device.c @@ -33,6 +33,9 @@ #ifdef HAVE_SYS_SYSMACROS_H # include /* for major, minor */ #endif +#ifdef HAVE_SYS_STATVFS_H +# include +#endif #include "internal.h" struct device { @@ -49,6 +52,28 @@ struct device { size_t block_size; }; +static size_t device_fs_block_size(const char *path) +{ +#ifdef HAVE_SYS_STATVFS_H + struct statvfs buf; + + if (!statvfs(path, &buf) && buf.f_bsize) + return (size_t)buf.f_bsize; +#endif + return crypt_getpagesize(); +} + +static size_t device_fs_block_size_fd(int fd) +{ +#ifdef HAVE_SYS_STATVFS_H + struct statvfs buf; + + if (!fstatvfs(fd, &buf) && buf.f_bsize) + return (size_t)buf.f_bsize; +#endif + return crypt_getpagesize(); +} + static size_t device_block_size_fd(int fd, size_t *min_size) { struct stat st; @@ -59,7 +84,7 @@ static size_t device_block_size_fd(int fd, size_t *min_size) return 0; if (S_ISREG(st.st_mode)) - bsize = crypt_getpagesize(); + bsize = device_fs_block_size_fd(fd); else { if (ioctl(fd, BLKSSZGET, &arg) < 0) bsize = crypt_getpagesize(); @@ -338,7 +363,7 @@ size_t device_block_size(struct device *device) return device->block_size; if (device->file_path) - device->block_size = crypt_getpagesize(); + device->block_size = device_fs_block_size(device->file_path); else { fd = open(device->path, O_RDONLY); if (fd >= 0) {