1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-02 01:18:26 +03:00

mirror: fix region_size for clustered VG

When adjusting region size for clustered VG it always needs to fit
2 full bitset into 1MB due to old limits of CPG.

This is relatively big amount of bits, but we have still limitation
for region size to fit into 32bits (0x8000000).

So for too big mirrors this operation needs to fail - so whenever
function returns now 0, it means we can't find matching region_size.

Since return 0 is now 'error' we need to also pass proper region_size
when creating pvmove mirror.
This commit is contained in:
Zdenek Kabelac 2018-04-20 10:07:42 +02:00
parent a19456b868
commit 66400d003d
6 changed files with 40 additions and 39 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
Detect too big region_size with clustered mirrors.
Fix evaluation of maximal region size for mirror log.
Enhance mirror log size estimation and use smaller size when possible.
Fix incorrect mirror log size calculation on 32bit arch.

View File

@ -7582,6 +7582,13 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return NULL;
}
if (!(lp->region_size = adjusted_mirror_region_size(vg->cmd,
vg->extent_size,
lp->extents,
lp->region_size, 0,
vg_is_clustered(vg))))
return_NULL;
/* FIXME This will not pass cluster lock! */
init_mirror_in_sync(lp->nosync);
@ -7591,19 +7598,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
lp->segtype->name);
status |= LV_NOTSYNCED;
}
if (seg_is_raid(lp)) {
/* Value raid target constraint */
if (lp->region_size > (uint64_t)vg->extent_size * lp->extents) {
log_error("Cannot create RAID LV with region size larger than LV size.");
return NULL;
}
} else
lp->region_size = adjusted_mirror_region_size(vg->cmd,
vg->extent_size,
lp->extents,
lp->region_size, 0,
vg_is_clustered(vg));
} else if (pool_lv && seg_is_thin_volume(lp)) {
if (!lv_is_thin_pool(pool_lv)) {
log_error("Logical volume %s is not a thin pool.",

View File

@ -193,10 +193,12 @@ uint32_t adjusted_mirror_region_size(struct cmd_context *cmd,
* This code should be removed when the CPG restriction is
* lifted.
*/
region_min = (uint64_t) extents * extent_size / CMIRROR_REGION_COUNT_LIMIT;
region_min_pow2 = 1;
while (region_min_pow2 < region_min)
region_min_pow2 *= 2;
region_min = region_max / CMIRROR_REGION_COUNT_LIMIT;
if (region_min > UINT32_MAX / 2) {
log_error("Can't find proper region size for too big mirror.");
return 0;
}
region_min_pow2 = UINT64_C(1) << (1 + 31 - clz(region_min));
if (region_size < region_min_pow2) {
if (internal)
@ -1591,11 +1593,12 @@ static int _add_mirrors_that_preserve_segments(struct logical_volume *lv,
if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_MIRROR)))
return_0;
adjusted_region_size = adjusted_mirror_region_size(cmd,
lv->vg->extent_size,
lv->le_count,
region_size, 1,
vg_is_clustered(lv->vg));
if (!(adjusted_region_size = adjusted_mirror_region_size(cmd,
lv->vg->extent_size,
lv->le_count,
region_size, 1,
vg_is_clustered(lv->vg))))
return_0;
if (!(ah = allocate_extents(lv->vg, NULL, segtype, 1, mirrors, 0, 0,
lv->le_count, allocatable_pvs, alloc, 0,

View File

@ -378,12 +378,12 @@ static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem
}
region_size = seg->region_size;
} else
region_size = adjusted_mirror_region_size(cmd,
seg->lv->vg->extent_size,
seg->area_len,
mirr_state->default_region_size, 1,
vg_is_clustered(seg->lv->vg));
} else if (!(region_size = adjusted_mirror_region_size(cmd,
seg->lv->vg->extent_size,
seg->area_len,
mirr_state->default_region_size, 1,
vg_is_clustered(seg->lv->vg))))
return_0;
if (!dm_tree_node_add_mirror_target(node, len))
return_0;

View File

@ -628,10 +628,11 @@ static int _lv_update_log_type(struct cmd_context *cmd,
/* Adding redundancy to the log */
if (old_log_count < log_count) {
region_size = adjusted_mirror_region_size(cmd, lv->vg->extent_size,
lv->le_count,
region_size, 0,
vg_is_clustered(lv->vg));
if (!(region_size = adjusted_mirror_region_size(cmd, lv->vg->extent_size,
lv->le_count,
region_size, 0,
vg_is_clustered(lv->vg))))
return_0;
if (!add_mirror_log(cmd, original_lv, log_count,
region_size, operable_pvs, alloc))
@ -833,17 +834,18 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
return 1;
}
if (!(region_size = adjusted_mirror_region_size(cmd, lv->vg->extent_size,
lv->le_count,
lp->region_size ? : seg->region_size, 0,
vg_is_clustered(lv->vg))))
return_0;
if (lv_component_is_active(lv)) {
log_error("Cannot convert logical volume %s with active component LV(s).",
display_lvname(lv));
return 0;
}
region_size = adjusted_mirror_region_size(cmd, lv->vg->extent_size,
lv->le_count,
lp->region_size ? : seg->region_size, 0,
vg_is_clustered(lv->vg));
if (!operable_pvs)
operable_pvs = pvh;

View File

@ -511,8 +511,9 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
return NULL;
}
if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0, 0, log_count,
allocatable_pvs, alloc,
if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0,
get_default_region_size(cmd),
log_count, allocatable_pvs, alloc,
(arg_is_set(cmd, atomic_ARG)) ?
MIRROR_BY_SEGMENTED_LV : MIRROR_BY_SEG)) {
log_error("Failed to convert pvmove LV to mirrored.");