172 lines
6.3 KiB
Diff
172 lines
6.3 KiB
Diff
From aa75359c7c1baae43349416f3761754507cd5c1a Mon Sep 17 00:00:00 2001
|
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
|
Date: Fri, 8 Jul 2022 23:38:34 +0200
|
|
Subject: [PATCH 079/115] vdo: enhance lvcreate validation
|
|
|
|
When creating VDO pool based of % values, lvm2 is now more clever
|
|
and avoids to create 'unsupportable' sizes of physical backend
|
|
volumes as 16TiB is maximum size supported by VDO target
|
|
(and also limited by maximum supportable slabs (8192) based on slab
|
|
size.
|
|
|
|
If the requested virtual size is approaching max supported size 4PiB,
|
|
switch header size to 0.
|
|
|
|
(cherry picked from commit e2e31d9acf1b96ab741c22dc0a2fefd672996d3a)
|
|
---
|
|
lib/metadata/metadata-exported.h | 2 ++
|
|
lib/metadata/vdo_manip.c | 14 ++++++++++
|
|
tools/lvcreate.c | 48 ++++++++++++++++++++++++++------
|
|
3 files changed, 56 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
|
|
index 449c8d014..f735baa55 100644
|
|
--- a/lib/metadata/metadata-exported.h
|
|
+++ b/lib/metadata/metadata-exported.h
|
|
@@ -1364,6 +1364,8 @@ const char *get_vdo_operating_mode_name(enum dm_vdo_operating_mode mode);
|
|
const char *get_vdo_write_policy_name(enum dm_vdo_write_policy policy);
|
|
uint64_t get_vdo_pool_virtual_size(const struct lv_segment *vdo_pool_seg);
|
|
int update_vdo_pool_virtual_size(struct lv_segment *vdo_pool_seg);
|
|
+uint32_t get_vdo_pool_max_extents(const struct dm_vdo_target_params *vtp,
|
|
+ uint32_t extent_size);
|
|
int parse_vdo_pool_status(struct dm_pool *mem, const struct logical_volume *vdo_pool_lv,
|
|
const char *params, const struct dm_info *dminfo,
|
|
struct lv_status_vdo *status);
|
|
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
|
|
index f3a4a9534..4ccde40b1 100644
|
|
--- a/lib/metadata/vdo_manip.c
|
|
+++ b/lib/metadata/vdo_manip.c
|
|
@@ -127,6 +127,20 @@ int update_vdo_pool_virtual_size(struct lv_segment *vdo_pool_seg)
|
|
return 1;
|
|
}
|
|
|
|
+uint32_t get_vdo_pool_max_extents(const struct dm_vdo_target_params *vtp,
|
|
+ uint32_t extent_size)
|
|
+{
|
|
+ uint64_t max_extents = (DM_VDO_PHYSICAL_SIZE_MAXIMUM + extent_size - 1) / extent_size;
|
|
+ uint64_t max_slab_extents = ((extent_size - 1 + DM_VDO_SLABS_MAXIMUM *
|
|
+ ((uint64_t)vtp->slab_size_mb << (20 - SECTOR_SHIFT))) /
|
|
+ extent_size);
|
|
+
|
|
+ max_extents = (max_slab_extents < max_extents) ? max_slab_extents : max_extents;
|
|
+
|
|
+ return (max_extents > UINT32_MAX) ? UINT32_MAX : (uint32_t)max_extents;
|
|
+}
|
|
+
|
|
+
|
|
static int _sysfs_get_kvdo_value(const char *dm_name, const struct dm_info *dminfo,
|
|
const char *vdo_param, uint64_t *value)
|
|
{
|
|
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
|
|
index fb57d84bd..3eee5de90 100644
|
|
--- a/tools/lvcreate.c
|
|
+++ b/tools/lvcreate.c
|
|
@@ -253,6 +253,7 @@ static int _update_extents_params(struct volume_group *vg,
|
|
uint32_t stripesize_extents;
|
|
uint32_t extents;
|
|
uint32_t base_calc_extents;
|
|
+ uint32_t vdo_pool_max_extents;
|
|
|
|
if (lcp->size &&
|
|
!(lp->extents = extents_from_size(vg->cmd, lcp->size,
|
|
@@ -322,6 +323,23 @@ static int _update_extents_params(struct volume_group *vg,
|
|
return 0;
|
|
}
|
|
|
|
+ if (seg_is_vdo(lp)) {
|
|
+ vdo_pool_max_extents = get_vdo_pool_max_extents(&lp->vdo_params, vg->extent_size);
|
|
+ if (extents > vdo_pool_max_extents) {
|
|
+ if (lcp->percent == PERCENT_NONE) {
|
|
+ log_error("Can't use %s size. Maximal supported VDO POOL volume size with slab size %s is %s.",
|
|
+ display_size(vg->cmd, (uint64_t)vg->extent_size * extents),
|
|
+ display_size(vg->cmd, (uint64_t)lp->vdo_params.slab_size_mb << (20 - SECTOR_SHIFT)),
|
|
+ display_size(vg->cmd, (uint64_t)vg->extent_size * vdo_pool_max_extents));
|
|
+ return 0;
|
|
+ }
|
|
+ extents = vdo_pool_max_extents;
|
|
+ log_verbose("Using maximal supported VDO POOL volume size %s (with slab size %s).",
|
|
+ display_size(vg->cmd, (uint64_t)vg->extent_size * extents),
|
|
+ display_size(vg->cmd, (uint64_t)lp->vdo_params.slab_size_mb << (20 - SECTOR_SHIFT)));
|
|
+ }
|
|
+ }
|
|
+
|
|
if (lcp->percent != PERCENT_NONE) {
|
|
/* FIXME Don't do the adjustment for parallel allocation with PERCENT_ORIGIN! */
|
|
lp->approx_alloc = 1;
|
|
@@ -699,15 +717,23 @@ static int _read_cache_params(struct cmd_context *cmd,
|
|
}
|
|
|
|
static int _read_vdo_params(struct cmd_context *cmd,
|
|
- struct lvcreate_params *lp)
|
|
+ struct lvcreate_params *lp,
|
|
+ struct lvcreate_cmdline_params *lcp)
|
|
{
|
|
if (!seg_is_vdo(lp))
|
|
return 1;
|
|
|
|
// prefiling settings here
|
|
- if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL))
|
|
+ if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL))
|
|
return_0;
|
|
|
|
+ if ((lcp->virtual_size <= DM_VDO_LOGICAL_SIZE_MAXIMUM) &&
|
|
+ ((lcp->virtual_size + lp->vdo_pool_header_size) > DM_VDO_LOGICAL_SIZE_MAXIMUM)) {
|
|
+ log_verbose("Dropping VDO pool header size to 0 to support maximal size %s.",
|
|
+ display_size(cmd, DM_VDO_LOGICAL_SIZE_MAXIMUM));
|
|
+ lp->vdo_pool_header_size = 0;
|
|
+ }
|
|
+
|
|
// override with optional vdo settings
|
|
if (!get_vdo_settings(cmd, &lp->vdo_params, NULL))
|
|
return_0;
|
|
@@ -1203,7 +1229,7 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
|
&lp->pool_metadata_size, &lp->pool_metadata_spare,
|
|
&lp->chunk_size, &lp->discards, &lp->zero_new_blocks)) ||
|
|
!_read_cache_params(cmd, lp) ||
|
|
- !_read_vdo_params(cmd, lp) ||
|
|
+ !_read_vdo_params(cmd, lp, lcp) ||
|
|
!_read_mirror_and_raid_params(cmd, lp))
|
|
return_0;
|
|
|
|
@@ -1589,13 +1615,19 @@ static int _check_pool_parameters(struct cmd_context *cmd,
|
|
}
|
|
|
|
static int _check_vdo_parameters(struct volume_group *vg, struct lvcreate_params *lp,
|
|
- struct lvcreate_cmdline_params *lcp)
|
|
+ struct lvcreate_cmdline_params *lcp)
|
|
{
|
|
- if (seg_is_vdo(lp) && lp->snapshot) {
|
|
+ if (lp->snapshot) {
|
|
log_error("Please either create VDO or snapshot.");
|
|
return 0;
|
|
}
|
|
|
|
+ if (lcp->virtual_size > DM_VDO_LOGICAL_SIZE_MAXIMUM) {
|
|
+ log_error("Maximal supported VDO virtual size is %s.",
|
|
+ display_size(vg->cmd, DM_VDO_LOGICAL_SIZE_MAXIMUM));
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
return 1;
|
|
}
|
|
|
|
@@ -1716,12 +1748,12 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name,
|
|
if (seg_is_thin(lp) && !_check_thin_parameters(vg, lp, lcp))
|
|
goto_out;
|
|
|
|
- if (!_check_pool_parameters(cmd, vg, lp, lcp))
|
|
- goto_out;
|
|
-
|
|
if (seg_is_vdo(lp) && !_check_vdo_parameters(vg, lp, lcp))
|
|
return_0;
|
|
|
|
+ if (!_check_pool_parameters(cmd, vg, lp, lcp))
|
|
+ goto_out;
|
|
+
|
|
/* All types are checked */
|
|
if (!_check_zero_parameters(cmd, lp))
|
|
return_0;
|
|
--
|
|
2.41.0
|
|
|