summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2019-09-09 18:21:20 +0100
committerJoe Thornber <ejt@redhat.com>2019-09-09 18:21:20 +0100
commit510a6e86a354537c981386e7a46d5f2c26855660 (patch)
tree5e0df4679bf58b0d240e2d242d0cd132a246f104
parente4693f7f8db38230362255ebc30d6b8a5bd40918 (diff)
parent13c702f862008192a36ee171e546ba0d247bcf9f (diff)
downloadlvm2-2019-09-05-add-io-manager.tar.gz
Merge branch '2019-09-05-add-io-manager' of git+ssh://sourceware.org/git/lvm2 into 2019-09-05-add-io-manager2019-09-05-add-io-manager
-rw-r--r--lib/device/io-manager.c62
-rw-r--r--lib/device/io-manager.h4
2 files changed, 36 insertions, 30 deletions
diff --git a/lib/device/io-manager.c b/lib/device/io-manager.c
index 9800eeefd..21a9e926d 100644
--- a/lib/device/io-manager.c
+++ b/lib/device/io-manager.c
@@ -436,39 +436,44 @@ static bool _common_get_size(struct io_engine *e, const char *path, int fd, uint
}
static bool _common_get_block_sizes(struct io_engine *e, const char *path, int fd,
- unsigned *physical, unsigned *block_size)
+ unsigned *physical_block_size,
+ unsigned *logical_block_size)
{
+ unsigned int pbs = 0;
+ unsigned int lbs = 0;
+
// There are 3 ioctls for getting a block size:
// BLKBSZGET - fs allocation unit size
// BLKPBSZGET - physical block size (kernel 2.6.32 onwards)
// BLKSSZGET - logical block size
- if (ioctl(fd, BLKBSZGET, block_size) < 0) {
- log_sys_error("ioctl BLKBSZGET", path);
- return false;
- }
- log_debug_devs("%s: Block size is %u bytes", path, *block_size);
-#ifdef BLKPBSZGET
- if (ioctl(fd, BLKPBSZGET, physical) < 0) {
- log_sys_error("ioctl BLKPBSZGET", path);
- return false;
- }
- log_debug_devs("%s: Physical block size is %u bytes", path, *physical);
-#elif defined (BLKSSZGET)
- if (ioctl(fd, BLKSSZGET, physical) < 0) {
- log_sys_error("ioctl BLKSSZGET", path);
- return false;
+#ifdef BLKPBSZGET /* not defined before kernel version 2.6.32 (e.g. rhel5) */
+ /*
+ * BLKPBSZGET from kernel comment for blk_queue_physical_block_size:
+ * "the lowest possible sector size that the hardware can operate on
+ * without reverting to read-modify-write operations"
+ */
+ if (ioctl(fd, BLKPBSZGET, &pbs)) {
+ log_debug_devs("No physical block size for %s", path);
+ pbs = 0;
}
- log_debug_devs("%s: Physical block size can't be determined: "
- "Using logical block size of %u bytes", path, physical);
-#else
- /* if even BLKSSZGET is not available, use default 512b */
- *physical = 512;
- log_debug_devs("%s: Physical block size can't be determined: "
- "Using block size of %u bytes instead", path, *physical);
#endif
+ /*
+ * BLKSSZGET from kernel comment for blk_queue_logical_block_size:
+ * "the lowest possible block size that the storage device can address."
+ */
+ if (ioctl(fd, BLKSSZGET, &lbs)) {
+ log_debug_devs("No logical block size for %s", path);
+ lbs = 0;
+ }
+
+ *physical_block_size = pbs;
+ *logical_block_size = lbs;
+
+ if (!lbs)
+ return false;
return true;
}
@@ -727,7 +732,7 @@ struct io_dev_internal {
// We cache these to avoid repeatedly issuing the ioctls
bool got_block_sizes;
unsigned physical_block_size;
- unsigned block_size;
+ unsigned logical_block_size;
struct dm_list lru;
};
@@ -2000,7 +2005,8 @@ bool io_dev_size(struct io_dev *dev, uint64_t *size)
return iom->engine->get_size(iom->engine, dev->idev->path, dev->idev->fd, size);
}
-bool io_dev_block_sizes(struct io_dev *dev, unsigned *physical, unsigned *block_size)
+bool io_dev_block_sizes(struct io_dev *dev, unsigned *physical_block_size,
+ unsigned *logical_block_size)
{
struct io_manager *iom = dev->idev->iom;
struct io_dev_internal *d = dev->idev;
@@ -2008,14 +2014,14 @@ bool io_dev_block_sizes(struct io_dev *dev, unsigned *physical, unsigned *block_
if (!d->got_block_sizes) {
if (!iom->engine->get_block_sizes(iom->engine, d->path, d->fd,
&d->physical_block_size,
- &d->block_size))
+ &d->logical_block_size))
return false;
else
d->got_block_sizes = true;
}
- *physical = dev->idev->physical_block_size;
- *block_size = dev->idev->block_size;
+ *physical_block_size = dev->idev->physical_block_size;
+ *logical_block_size = dev->idev->logical_block_size;
return true;
}
diff --git a/lib/device/io-manager.h b/lib/device/io-manager.h
index 253b3ad22..923d0be64 100644
--- a/lib/device/io-manager.h
+++ b/lib/device/io-manager.h
@@ -61,7 +61,7 @@ struct io_engine {
// The path is there purely for logging.
bool (*get_size)(struct io_engine *e, const char *path, int fd, sector_t *size);
bool (*get_block_sizes)(struct io_engine *e, const char *path, int fd,
- unsigned *physical, unsigned *logical);
+ unsigned *physical_block_size, unsigned *logical_block_size);
};
struct io_engine *create_async_io_engine(void);
@@ -198,7 +198,7 @@ bool io_invalidate_dev(struct io_manager *iom, struct io_dev *dev);
bool io_invalidate_all(struct io_manager *iom);
bool io_dev_size(struct io_dev *dev, uint64_t *sectors);
-bool io_dev_block_sizes(struct io_dev *dev, unsigned *physical, unsigned *block_size);
+bool io_dev_block_sizes(struct io_dev *dev, unsigned *physical_block_size, unsigned *logical_block_size);
// For testing and debug only
void *io_get_dev_context(struct io_dev *dev);