9ac44fb8d2
Resolves: #2173312
99 lines
3.5 KiB
Diff
99 lines
3.5 KiB
Diff
From c66a3010e0b90a5eb2a17717ecc73f62859d1eea Mon Sep 17 00:00:00 2001
|
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
|
Date: Sat, 5 Nov 2022 23:10:36 +0100
|
|
Subject: [PATCH 089/115] vdo: enhance detection of virtual size
|
|
|
|
Improve detection of VDO virtual size - so it's not reading VDO
|
|
metadata when VDO device is already active and instead we reuse
|
|
existing table line for knowing existing metadata size.
|
|
|
|
NOTE: if there is ever going to be added support for reduction
|
|
of VDO virtual size - this method will need to be reworked to
|
|
allow size difference only within 'extent_size' alignment.
|
|
|
|
(cherry picked from commit 8e9410594b3113386a667df400b2c229c745cb6a)
|
|
---
|
|
device_mapper/libdm-deptree.c | 44 ++++++++++++++++++++++++-----------
|
|
1 file changed, 31 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c
|
|
index 02a56c8e3..39af7b1d4 100644
|
|
--- a/device_mapper/libdm-deptree.c
|
|
+++ b/device_mapper/libdm-deptree.c
|
|
@@ -2850,7 +2850,7 @@ static int _thin_pool_emit_segment_line(struct dm_task *dmt,
|
|
return 1;
|
|
}
|
|
|
|
-static int _vdo_emit_segment_line(struct dm_task *dmt,
|
|
+static int _vdo_emit_segment_line(struct dm_task *dmt, uint32_t major, uint32_t minor,
|
|
struct load_segment *seg,
|
|
char *params, size_t paramsize)
|
|
{
|
|
@@ -2858,6 +2858,10 @@ static int _vdo_emit_segment_line(struct dm_task *dmt,
|
|
char data[DM_FORMAT_DEV_BUFSIZE];
|
|
char data_dev[128]; // for /dev/dm-XXXX
|
|
uint64_t logical_blocks;
|
|
+ struct dm_task *vdo_dmt;
|
|
+ uint64_t start, length = 0;
|
|
+ char *type = NULL;
|
|
+ char *vdo_params = NULL;
|
|
|
|
if (!_build_dev_string(data, sizeof(data), seg->vdo_data))
|
|
return_0;
|
|
@@ -2867,18 +2871,32 @@ static int _vdo_emit_segment_line(struct dm_task *dmt,
|
|
return 0;
|
|
}
|
|
|
|
- if (dm_vdo_parse_logical_size(data_dev, &logical_blocks)) {
|
|
- logical_blocks *= 8;
|
|
- if (seg->size != logical_blocks) {
|
|
- if (seg->size > logical_blocks) {
|
|
- log_error("Virtual size of VDO volume is smaller then expected (" FMTu64 " > " FMTu64 ").",
|
|
- seg->size, logical_blocks);
|
|
- return 1;
|
|
- }
|
|
- log_debug_activation("Increasing VDO virtual volume size from " FMTu64 " to " FMTu64 ".",
|
|
- seg->size, logical_blocks);
|
|
- seg->size = logical_blocks;
|
|
+ /*
|
|
+ * If there is already running VDO target, read 'existing' virtual size out of table line
|
|
+ * and avoid reading it them from VDO metadata device
|
|
+ *
|
|
+ * NOTE: ATM VDO virtual size can be ONLY extended thus it's simple to recongnize 'right' size.
|
|
+ * However if there would be supported also reduction, this check would need to check range.
|
|
+ */
|
|
+ if ((vdo_dmt = dm_task_create(DM_DEVICE_TABLE))) {
|
|
+ if (dm_task_set_major(vdo_dmt, major) &&
|
|
+ dm_task_set_minor(vdo_dmt, minor) &&
|
|
+ dm_task_run(vdo_dmt)) {
|
|
+ (void) dm_get_next_target(vdo_dmt, NULL, &start, &length, &type, &vdo_params);
|
|
+ if (!type || strcmp(type, "vdo"))
|
|
+ length = 0;
|
|
}
|
|
+
|
|
+ dm_task_destroy(vdo_dmt);
|
|
+ }
|
|
+
|
|
+ if (!length && dm_vdo_parse_logical_size(data_dev, &logical_blocks))
|
|
+ length = logical_blocks * 8;
|
|
+
|
|
+ if (seg->size < length) {
|
|
+ log_debug_activation("Correcting VDO virtual volume size from " FMTu64 " to " FMTu64 ".",
|
|
+ seg->size, length);
|
|
+ seg->size = length;
|
|
}
|
|
|
|
if (seg->vdo_version < 4) {
|
|
@@ -2980,7 +2998,7 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
|
|
EMIT_PARAMS(pos, "%u %u ", seg->area_count, seg->stripe_size);
|
|
break;
|
|
case SEG_VDO:
|
|
- if (!_vdo_emit_segment_line(dmt, seg, params, paramsize))
|
|
+ if (!_vdo_emit_segment_line(dmt, major, minor, seg, params, paramsize))
|
|
return_0;
|
|
break;
|
|
case SEG_CRYPT:
|
|
--
|
|
2.41.0
|
|
|