mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-19 14:04:17 +03:00
raid_manip:
fix data_copies on TAKEOVER_FN calls fix _lv_free_reshape_space() reshape_len add more possible_types conversion raid: add descriptor field to segment types to display on failing conversion merge: remove now superfluous _data_rimages_count() all: comments
This commit is contained in:
parent
1dd4629cac
commit
9399e2b75a
@ -1290,11 +1290,11 @@ static int _lv_segment_add_areas(struct logical_volume *lv,
|
||||
/* Return area_len for @extents based on @seg's properties (e.g. striped, ...) */
|
||||
static uint32_t _seg_area_len(struct lv_segment *seg, uint32_t extents)
|
||||
{
|
||||
uint32_t r;
|
||||
uint32_t stripes = seg->area_count - ((seg->area_count > 2) ? seg->segtype->parity_devs : 0);
|
||||
/* Prevent parity_devs to be subtracted in case of 2 devs raid4/5 */
|
||||
uint32_t r, stripes = seg->area_count - (seg->area_count > 2 ? seg->segtype->parity_devs : 0);
|
||||
|
||||
PFLA("lv=%s extents=%u", display_lvname(seg->lv), extents);
|
||||
PFLA("segtype=%s stripes=%u data_copies=%u", lvseg_name(seg), stripes, seg->data_copies);
|
||||
PFLA("segtype=%s seg->reshape_len=%u stripes=%u data_copies=%u", lvseg_name(seg), seg->reshape_len, stripes, seg->data_copies);
|
||||
r = raid_rimage_extents(seg->segtype, extents - seg->reshape_len * stripes,
|
||||
stripes, seg->data_copies ?: 1);
|
||||
PFLA("area_len=%u", r);
|
||||
@ -1809,13 +1809,10 @@ PFLA("extend=%u existing_extents=%u, new_extents=%u, area_count=%u mirrors=%u st
|
||||
* exists and they only want replacement drives.
|
||||
*/
|
||||
/* HM FIXME: avoid this overload to define the parity_count to allocate! */
|
||||
#if 0
|
||||
parity_count = (area_count <= segtype->parity_devs) ? 0 : segtype->parity_devs;
|
||||
parity_count = segtype->parity_devs;
|
||||
#else
|
||||
parity_count = extend ? 0 : segtype->parity_devs;
|
||||
#endif
|
||||
|
||||
alloc_count = area_count + parity_count;
|
||||
|
||||
PFLA("alloc_count=%u parity_count=%u metadata_area_count=%u", alloc_count, parity_count, metadata_area_count);
|
||||
if (segtype_is_raid(segtype) && metadata_area_count) {
|
||||
/* RAID has a meta area for each device */
|
||||
@ -1866,7 +1863,7 @@ PFLA("alloc_count=%u parity_count=%u metadata_area_count=%u", alloc_count, parit
|
||||
ah->mirror_logs_separate = find_config_tree_bool(cmd, allocation_mirror_logs_require_separate_pvs_CFG, NULL);
|
||||
|
||||
total_extents = new_extents;
|
||||
PFLA("ah->area_multiple=%u area_count=%u new_extents=%u total_extents=%u", ah->area_multiple, area_count, new_extents, total_extents);
|
||||
PFLA("ah->area_multiple=%u area_count=%u new_extents=%u total_extents=%u stripes=%u mirrors=%u", ah->area_multiple, area_count, new_extents, total_extents, stripes, mirrors);
|
||||
if (segtype_is_raid(segtype)) {
|
||||
#if 1
|
||||
total_extents = raid_total_extents(segtype, total_extents, stripes, mirrors);
|
||||
@ -4394,14 +4391,15 @@ PFLA("recursive seg_lv(seg, %u)=%s extents=%u", s, display_lvname(lv1), extents)
|
||||
mirrors = seg->data_copies;
|
||||
|
||||
} else {
|
||||
area_count = seg->data_copies;
|
||||
stripes = 1;
|
||||
area_count = mirrors = seg->data_copies;
|
||||
mirrors = seg->data_copies;
|
||||
}
|
||||
|
||||
} else
|
||||
area_count = max(stripes + segtype->parity_devs, mirrors);
|
||||
|
||||
PFLA("mirrors=%u stripes=%u", mirrors, stripes);
|
||||
PFLA("area_count=%u mirrors=%u stripes=%u", area_count, mirrors, stripes);
|
||||
if (segtype_is_virtual(segtype))
|
||||
return lv_add_virtual_segment(lv, 0u, extents, segtype);
|
||||
|
||||
@ -4444,7 +4442,7 @@ PFLA("extents=%u mirrors=%u stripes=%u log_count=%u", extents, mirrors, stripes,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(ah = allocate_extents(lv->vg, lv, segtype, (lv->le_count && mirrors == 1) ? area_count : stripes, mirrors,
|
||||
if (!(ah = allocate_extents(lv->vg, lv, segtype, stripes, mirrors,
|
||||
log_count, region_size, extents,
|
||||
allocatable_pvs, alloc, approx_alloc, NULL)))
|
||||
return_0;
|
||||
|
@ -70,20 +70,6 @@ int lv_merge_segments(struct logical_volume *lv)
|
||||
if (error_count++ > ERROR_MAX) \
|
||||
goto out
|
||||
|
||||
/* Return number of data rimages for @seg paying attention to delta disks (reshaping) */
|
||||
static uint32_t _data_rimage_count(struct lv_segment *seg)
|
||||
{
|
||||
uint32_t r = seg->area_count - seg->segtype->parity_devs, s;
|
||||
|
||||
#if 0
|
||||
for (s = 0; s < seg->area_count; s++)
|
||||
if (seg_type(seg, s) == AREA_LV &&
|
||||
(seg_lv(seg, s)->status & LV_RESHAPE_DELTA_DISKS_MINUS))
|
||||
r--;
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
/*
|
||||
* Verify that an LV's segments are consecutive, complete and don't overlap.
|
||||
*/
|
||||
@ -155,7 +141,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
|
||||
}
|
||||
|
||||
area_multiplier = (seg_is_striped_raid(seg) || seg_is_striped(seg)) ? seg->area_count - seg->segtype->parity_devs : 1;
|
||||
data_rimage_count = _data_rimage_count(seg);
|
||||
data_rimage_count = seg->area_count - seg->segtype->parity_devs;
|
||||
|
||||
PFLA("lv=%s segtype=%s seg->len=%u seg->area_len=%u seg->area_count=%u data_rimage_count=%u parity_devs=%u area_multiplier=%u seg->data_copies=%u rimageextents=%u seg->reshape_len=%u", lv->name, seg->segtype->name, seg->len, seg->area_len, seg->area_count, data_rimage_count, seg->segtype->parity_devs, area_multiplier, seg->data_copies, raid_rimage_extents(seg->segtype, seg->len - data_rimage_count * seg->reshape_len, data_rimage_count, seg->data_copies), seg->reshape_len);
|
||||
#if 1
|
||||
|
@ -1149,7 +1149,7 @@ int lv_raid_split_and_track(struct logical_volume *lv,
|
||||
struct dm_list *splittable_pvs);
|
||||
int lv_raid_merge(struct logical_volume *lv);
|
||||
int lv_raid_convert(struct logical_volume *lv,
|
||||
const struct segment_type *new_segtype,
|
||||
struct segment_type *new_segtype,
|
||||
int yes, int force,
|
||||
int duplicate, int unduplicate,
|
||||
const int data_copies,
|
||||
|
@ -236,21 +236,13 @@ uint32_t raid_rimage_extents(const struct segment_type *segtype,
|
||||
segtype_is_raid1(segtype))
|
||||
return extents;
|
||||
|
||||
/* Caller should ensure... */
|
||||
if (!stripes)
|
||||
stripes = 1;
|
||||
|
||||
if (!segtype_is_raid(segtype) ||
|
||||
segtype_is_raid01(segtype))
|
||||
return extents / stripes;
|
||||
|
||||
r = extents;
|
||||
if (segtype_is_any_raid10(segtype))
|
||||
/* Caller should ensure... */
|
||||
r *= data_copies ?: 1;
|
||||
r *= (data_copies ?: 1); /* Caller should ensure data_copies > 0 */
|
||||
|
||||
r = dm_div_up(r, stripes);
|
||||
r = dm_div_up(r, (stripes ?: 1)); /* Caller should ensure stripes > 0 */
|
||||
|
||||
PFLA("r=%llu", (unsigned long long) r);
|
||||
return r > UINT_MAX ? 0 : (uint32_t) r;
|
||||
}
|
||||
|
||||
@ -538,9 +530,8 @@ static int _yes_no_conversion(const struct logical_volume *lv,
|
||||
|
||||
RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
|
||||
RETURN_IF_ZERO(new_data_copies, "new data copies");
|
||||
RETURN_IF_ZERO(new_segtype, "segment type argument");
|
||||
|
||||
new_segtype_tmp = (struct segment_type *) new_segtype; /* Drop const */
|
||||
RETURN_IF_ZERO((new_segtype_tmp = (struct segment_type *) new_segtype), /* Drop const */
|
||||
"segment type argument");
|
||||
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) && driver_version(NULL, 0)) {
|
||||
log_error("Unable to retrieve logical volume information: aborting");
|
||||
@ -2309,8 +2300,12 @@ PFL();
|
||||
RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
|
||||
|
||||
if (_reshape_len_per_dev(seg)) {
|
||||
uint32_t total_reshape_len = _reshape_len_per_dev(seg) *
|
||||
_data_rimages_count(seg, seg->area_count);
|
||||
|
||||
/*
|
||||
* Got reshape space on request to free it.
|
||||
*
|
||||
* If it happens to be at the beginning of
|
||||
* the data LVs, remap it to the end in order
|
||||
* to be able to free it via lv_reduce().
|
||||
@ -2318,11 +2313,11 @@ PFL();
|
||||
if (!_lv_alloc_reshape_space(lv, alloc_end, NULL))
|
||||
return_0;
|
||||
|
||||
/* Reset reshape length upfront lv_reduce() to allow it to set area_len ... properly */
|
||||
/* Reset reshape length upfront lv_reduce() to allow it to set sgement len+area_len properly */
|
||||
if (!_lv_set_reshape_len(lv, 0))
|
||||
return 0;
|
||||
|
||||
if (!lv_reduce(lv, _reshape_len_per_dev(seg) * _data_rimages_count(seg, seg->area_count)))
|
||||
if (!lv_reduce(lv, total_reshape_len))
|
||||
return_0;
|
||||
|
||||
seg->data_offset = 0;
|
||||
@ -2379,7 +2374,9 @@ static int _reset_flags_passed_to_kernel(struct logical_volume *lv, int *flag_cl
|
||||
|
||||
*flag_cleared = 0;
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
RETURN_IF_ZERO(seg_type(seg, s) == AREA_LV, "sub image lv");
|
||||
if (seg_type(seg, s) == AREA_PV)
|
||||
continue;
|
||||
|
||||
slv = seg_lv(seg, s);
|
||||
#if 1
|
||||
if (slv->status & LV_RESHAPE_DELTA_DISKS_MINUS) {
|
||||
@ -3331,11 +3328,11 @@ static int _striped_to_raid0_move_segs_to_raid0_lvs(struct logical_volume *lv,
|
||||
|
||||
/* Allocate a segment with one area for each segment in the striped LV */
|
||||
if (!(seg_new = alloc_lv_segment(segtype, dlv,
|
||||
le, seg_from->area_len - seg_from->reshape_len,
|
||||
seg_from->reshape_len, status,
|
||||
seg_from->stripe_size, NULL, 1 /* area_count */,
|
||||
seg_from->area_len, seg_from->data_copies,
|
||||
seg_from->chunk_size, 0 /* region_size */, 0, NULL)))
|
||||
le, seg_from->area_len,
|
||||
0 /* reshape_len */, status,
|
||||
0 /* stripe_size */, NULL, 1 /* area_count */,
|
||||
seg_from->area_len, 1 /* data_copies */,
|
||||
0 /* chunk_size */, 0 /* region_size */, 0, NULL)))
|
||||
return_0;
|
||||
|
||||
seg_type(seg_new, 0) = AREA_UNASSIGNED;
|
||||
@ -3413,8 +3410,8 @@ static struct lv_segment *_convert_striped_to_raid0(struct logical_volume *lv,
|
||||
int alloc_metadata_devs,
|
||||
int update_and_reload)
|
||||
{
|
||||
uint32_t area_count, area_len = 0, stripe_size;
|
||||
struct lv_segment *seg, *raid0_seg;
|
||||
unsigned area_count;
|
||||
struct segment_type *segtype;
|
||||
struct dm_list data_lvs;
|
||||
|
||||
@ -3427,6 +3424,12 @@ static struct lv_segment *_convert_striped_to_raid0(struct logical_volume *lv,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dm_list_iterate_items(seg, &lv->segments)
|
||||
area_len += seg->area_len;
|
||||
|
||||
seg = first_seg(lv);
|
||||
stripe_size = seg->stripe_size;
|
||||
|
||||
/* Check for not (yet) supported varying area_count on multi-segment striped LVs */
|
||||
if (!_lv_has_one_stripe_zone(lv)) {
|
||||
log_error("Cannot convert striped LV %s with varying stripe count to raid0",
|
||||
@ -3467,9 +3470,9 @@ static struct lv_segment *_convert_striped_to_raid0(struct logical_volume *lv,
|
||||
if (!(raid0_seg = alloc_lv_segment(segtype, lv,
|
||||
0 /* le */, lv->le_count /* len */,
|
||||
0 /* reshape_len */, seg->status,
|
||||
seg->stripe_size, NULL /* log_lv */,
|
||||
area_count, seg->area_len,
|
||||
seg->data_copies, seg->chunk_size,
|
||||
stripe_size, NULL /* log_lv */,
|
||||
area_count, area_len,
|
||||
1 /* data_copies */, 0 /* chunk_size */,
|
||||
0 /* seg->region_size */, 0u /* extents_copied */ ,
|
||||
NULL /* pvmove_source_seg */))) {
|
||||
log_error("Failed to allocate new raid0 segement for LV %s.", display_lvname(lv));
|
||||
@ -4291,20 +4294,20 @@ static struct possible_takeover_reshape_type _possible_takeover_reshape_types[]
|
||||
.options = ALLOW_REGION_SIZE },
|
||||
|
||||
/* raid0* -> */
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count > 0 */
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count = 1 */
|
||||
.possible_types = SEG_RAID1,
|
||||
.current_areas = ~0U,
|
||||
.current_areas = 1,
|
||||
.options = ALLOW_DATA_COPIES|ALLOW_REGION_SIZE },
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count > 0 */
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count > 1 */
|
||||
.possible_types = SEG_RAID10_NEAR|SEG_RAID10_FAR,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_DATA_COPIES|ALLOW_REGION_SIZE },
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count > 0 */
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count > 1 */
|
||||
.possible_types = SEG_RAID4|SEG_RAID5_LS|SEG_RAID5_LA|SEG_RAID5_RS|SEG_RAID5_RA|SEG_RAID5_N|SEG_RAID6_N_6,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_REGION_SIZE },
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* raid0 striped, i.e. seg->area_count > 0 */
|
||||
.possible_types = SEG_AREAS_STRIPED,
|
||||
.possible_types = SEG_AREAS_STRIPED|SEG_RAID0|SEG_RAID0_META,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_NONE },
|
||||
|
||||
@ -4376,15 +4379,18 @@ static struct possible_takeover_reshape_type _possible_takeover_reshape_types[]
|
||||
|
||||
/* raid6 -> */
|
||||
{ .current_types = SEG_RAID6_ZR,
|
||||
.possible_types = SEG_RAID6_NC|SEG_RAID6_NR|SEG_RAID6_N_6,
|
||||
.possible_types = SEG_RAID6_LS_6|SEG_RAID6_LA_6|SEG_RAID6_RS_6|SEG_RAID6_RA_6| \
|
||||
SEG_RAID6_NC|SEG_RAID6_NR|SEG_RAID6_N_6,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_STRIPE_SIZE },
|
||||
{ .current_types = SEG_RAID6_NC,
|
||||
.possible_types = SEG_RAID6_NR|SEG_RAID6_ZR|SEG_RAID6_N_6,
|
||||
.possible_types = SEG_RAID6_LS_6|SEG_RAID6_LA_6|SEG_RAID6_RS_6|SEG_RAID6_RA_6| \
|
||||
SEG_RAID6_NR|SEG_RAID6_ZR|SEG_RAID6_N_6,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_STRIPE_SIZE },
|
||||
{ .current_types = SEG_RAID6_NR,
|
||||
.possible_types = SEG_RAID6_NC|SEG_RAID6_ZR|SEG_RAID6_N_6,
|
||||
.possible_types = SEG_RAID6_LS_6|SEG_RAID6_LA_6|SEG_RAID6_RS_6|SEG_RAID6_RA_6| \
|
||||
SEG_RAID6_NC|SEG_RAID6_ZR|SEG_RAID6_N_6,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_STRIPE_SIZE },
|
||||
{ .current_types = SEG_RAID6_LS_6,
|
||||
@ -4413,7 +4419,7 @@ static struct possible_takeover_reshape_type _possible_takeover_reshape_types[]
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_STRIPE_SIZE },
|
||||
{ .current_types = SEG_RAID6_N_6,
|
||||
.possible_types = SEG_AREAS_STRIPED|SEG_RAID0|SEG_RAID0_META|SEG_RAID4,
|
||||
.possible_types = SEG_AREAS_STRIPED|SEG_RAID0|SEG_RAID0_META|SEG_RAID4|SEG_RAID5_N,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_NONE },
|
||||
|
||||
@ -4463,10 +4469,12 @@ static struct possible_takeover_reshape_type *__get_possible_takeover_reshape_ty
|
||||
|
||||
RETURN_IF_ZERO(seg_from, "segment from argument");
|
||||
|
||||
PFLA("seg_from=%s segtype_to=%s", lvseg_name(seg_from), segtype_to ? segtype_to->name : "NIL");
|
||||
|
||||
for ( ; pt->current_types; pt++) {
|
||||
if ((seg_from->segtype->flags & pt->current_types) &&
|
||||
(segtype_to ? (segtype_to->flags & pt->possible_types) : 1)) {
|
||||
found = 1;
|
||||
// found = 1;
|
||||
if (seg_from->area_count <= pt->current_areas)
|
||||
return pt;
|
||||
|
||||
@ -4570,7 +4578,7 @@ static int _log_possible_conversion_types(struct logical_volume *lv, const struc
|
||||
t = 1ULL << i;
|
||||
if ((t & pt->possible_types) &&
|
||||
((segtype = get_segtype_from_flag(lv->vg->cmd, t))))
|
||||
log_warn("%s", segtype->name);
|
||||
log_warn("%s%s%s", segtype->name, segtype->descr ? " -> " : "", segtype->descr);
|
||||
}
|
||||
|
||||
log_warn("To convert to other arbitrary layouts by duplication, use \"lvconvert --duplicate ...\"");
|
||||
@ -4592,16 +4600,16 @@ static uint64_t _r5_to_r6[][2] = {
|
||||
|
||||
|
||||
/* Return segment type flag for raid5 -> raid6 conversions */
|
||||
static uint64_t _get_r56_flag(const struct lv_segment *seg, unsigned idx1, unsigned idx2)
|
||||
static uint64_t _get_r56_flag(const struct lv_segment *seg, unsigned idx)
|
||||
{
|
||||
unsigned elems = ARRAY_SIZE(_r5_to_r6);
|
||||
|
||||
RETURN_IF_ZERO(seg, "lv segment argument");
|
||||
RETURN_IF_ZERO(idx1 != idx2, "suitable index arguments");
|
||||
RETURN_IF_NONZERO(idx > 1, "proper index");
|
||||
|
||||
while (elems--)
|
||||
if (seg->segtype->flags & _r5_to_r6[elems][idx1])
|
||||
return _r5_to_r6[elems][idx2];
|
||||
if (seg->segtype->flags & _r5_to_r6[elems][idx])
|
||||
return _r5_to_r6[elems][!idx];
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -4611,7 +4619,7 @@ static uint64_t _raid_seg_flag_5_to_6(const struct lv_segment *seg)
|
||||
{
|
||||
RETURN_IF_ZERO(seg, "lv segment argument");
|
||||
|
||||
return _get_r56_flag(seg, 0, 1);
|
||||
return _get_r56_flag(seg, 0);
|
||||
}
|
||||
|
||||
/* Return segment type flag for raid6 -> raid5 conversions */
|
||||
@ -4619,7 +4627,8 @@ static uint64_t _raid_seg_flag_6_to_5(const struct lv_segment *seg)
|
||||
{
|
||||
RETURN_IF_ZERO(seg, "lv segment argument");
|
||||
|
||||
return _get_r56_flag(seg, 1, 0);
|
||||
PFL();
|
||||
return _get_r56_flag(seg, 1);
|
||||
}
|
||||
/******* END: raid <-> raid conversion *******/
|
||||
|
||||
@ -5976,7 +5985,7 @@ TAKEOVER_HELPER_FN(_raid0_mirror)
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
|
||||
|
||||
if (seg->area_count != 1)
|
||||
return _error(lv, new_segtype, yes, force, 0, 0 /* data_copies */, 0, 0, NULL);
|
||||
return _error(lv, new_segtype, yes, force, 0, 1 /* data_copies */, 0, 0, NULL);
|
||||
|
||||
new_image_count = new_image_count > 1 ? new_image_count : 2;
|
||||
|
||||
@ -6078,7 +6087,7 @@ TAKEOVER_HELPER_FN(_mirror_raid0)
|
||||
if (!_lv_is_synced(lv))
|
||||
return 0;
|
||||
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count, 0, 0, 0))
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count, 1, 0, 0))
|
||||
return 0;
|
||||
|
||||
/* Archive metadata */
|
||||
@ -6165,7 +6174,7 @@ TAKEOVER_HELPER_FN(_raid1_raid0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count, 0, 0, 0))
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count, 1, 0, 0))
|
||||
return 0;
|
||||
|
||||
/* Archive metadata */
|
||||
@ -6206,7 +6215,7 @@ PFLA("new_stripes=%u new_image_count=%u", new_stripes, new_image_count);
|
||||
if (!_raid_in_sync(lv))
|
||||
return 0;
|
||||
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count, 0, 0, 0))
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count, 1, 0, 0))
|
||||
return 0;
|
||||
|
||||
/* Archive metadata */
|
||||
@ -6262,7 +6271,7 @@ PFL();
|
||||
if (!_raid_in_sync(lv))
|
||||
return 0;
|
||||
PFL();
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count, 0, 0, 0))
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count, 1, 0, 0))
|
||||
return 0;
|
||||
|
||||
/* Archive metadata */
|
||||
@ -6456,7 +6465,7 @@ TAKEOVER_HELPER_FN_REMOVAL_LVS(_raid10_striped_r0)
|
||||
if (!_raid_in_sync(lv))
|
||||
return 0;
|
||||
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count, 0, 0, 0))
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count, 1, 0, 0))
|
||||
return 0;
|
||||
|
||||
/* Archive metadata */
|
||||
@ -6627,7 +6636,7 @@ TAKEOVER_FN(_s_r0)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, 0, 0, 0, 0))
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, 0, 1, 0, 0))
|
||||
return 0;
|
||||
|
||||
/* Archive metadata */
|
||||
@ -6642,7 +6651,7 @@ TAKEOVER_FN(_s_r0m)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, 0, 0, 0, 0))
|
||||
if (!_yes_no_conversion(lv, new_segtype, yes, force, 0, 1, 0, 0))
|
||||
return 0;
|
||||
|
||||
/* Archive metadata */
|
||||
@ -6680,7 +6689,7 @@ TAKEOVER_FN(_m_r0)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _mirror_raid0(lv, new_segtype, yes, force, 1, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _mirror_raid0(lv, new_segtype, yes, force, 1, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* mirror -> raid0_meta */
|
||||
@ -6688,7 +6697,7 @@ TAKEOVER_FN(_m_r0m)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _mirror_raid0(lv, new_segtype, yes, force, 1, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _mirror_raid0(lv, new_segtype, yes, force, 1, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* Mirror -> raid1 */
|
||||
@ -6716,7 +6725,7 @@ TAKEOVER_FN(_m_r45)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _mirror_r45(lv, new_segtype, yes, force, 0, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _mirror_r45(lv, new_segtype, yes, force, 0, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* Mirror with 2 images -> raid10 */
|
||||
@ -6754,7 +6763,7 @@ TAKEOVER_FN(_r0_l)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _raid0_linear(lv, new_segtype, yes, force, 0, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid0_linear(lv, new_segtype, yes, force, 0, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid0 with one image -> mirror */
|
||||
@ -6762,7 +6771,7 @@ TAKEOVER_FN(_r0_m)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _raid0_mirror(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid0_mirror(lv, new_segtype, yes, force, new_image_count, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid0 -> raid0_meta */
|
||||
@ -6798,7 +6807,7 @@ TAKEOVER_FN(_r0_r1)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _raid0_raid1(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid0_raid1(lv, new_segtype, yes, force, new_image_count, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid0 -> raid4/5_n */
|
||||
@ -6806,7 +6815,7 @@ TAKEOVER_FN(_r0_r45)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid0 -> raid6_n_6 */
|
||||
@ -6814,7 +6823,7 @@ TAKEOVER_FN(_r0_r6)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 2, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 2, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid0 with N images (N > 1) -> raid10 */
|
||||
@ -6830,7 +6839,7 @@ TAKEOVER_FN(_r0m_l)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _raid0_linear(lv, new_segtype, yes, force, 0, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid0_linear(lv, new_segtype, yes, force, 0, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid0_meta -> mirror */
|
||||
@ -6838,7 +6847,7 @@ TAKEOVER_FN(_r0m_m)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _raid0_mirror(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid0_mirror(lv, new_segtype, yes, force, new_image_count, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid0_meta -> raid0 */
|
||||
@ -6878,7 +6887,7 @@ TAKEOVER_FN(_r0m_r1)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _raid0_raid1(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid0_raid1(lv, new_segtype, yes, force, new_image_count, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid0_meta -> raid4/5_n */
|
||||
@ -6886,7 +6895,7 @@ TAKEOVER_FN(_r0m_r45)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid0_meta -> raid6_n_6 */
|
||||
@ -6894,7 +6903,7 @@ TAKEOVER_FN(_r0m_r6)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 2, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 2, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
|
||||
@ -6962,7 +6971,7 @@ TAKEOVER_FN(_r1_r0)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _raid1_raid0(lv, new_segtype, yes, force, 1, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid1_raid0(lv, new_segtype, yes, force, 1, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid1 -> raid0_meta */
|
||||
@ -6970,14 +6979,14 @@ TAKEOVER_FN(_r1_r0m)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _raid1_raid0(lv, new_segtype, yes, force, 1, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid1_raid0(lv, new_segtype, yes, force, 1, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
TAKEOVER_FN(_r1_r1)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _raid145_raid1_raid6(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid145_raid1_raid6(lv, new_segtype, yes, force, new_image_count, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid1 with 2 legs -> raid4/5 */
|
||||
@ -6992,7 +7001,7 @@ TAKEOVER_FN(_r1_r45)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _raid145_raid4510(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid145_raid4510(lv, new_segtype, yes, force, new_image_count, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
/****************************************************************************/
|
||||
|
||||
@ -7008,7 +7017,7 @@ TAKEOVER_FN(_r1_r10)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return _raid145_raid4510(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0 /* stripes */, 0, allocate_pvs);
|
||||
return _raid145_raid4510(lv, new_segtype, yes, force, new_image_count, 1 /* data_copies */, 0 /* stripes */, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid45 with 2 images -> linear */
|
||||
@ -7031,7 +7040,7 @@ TAKEOVER_FN(_r45_s)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
PFL();
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid4/5 with 2 images -> mirror */
|
||||
@ -7039,7 +7048,7 @@ TAKEOVER_FN(_r45_m)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _mirror_r45(lv, new_segtype, yes, force, 0, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _mirror_r45(lv, new_segtype, yes, force, 0, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid4/5 -> raid0 */
|
||||
@ -7047,7 +7056,7 @@ TAKEOVER_FN(_r45_r0)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid4/5 -> raid0_meta */
|
||||
@ -7055,7 +7064,7 @@ TAKEOVER_FN(_r45_r0m)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid4 with 2 images or raid5_n with 3 images -> raid1 */
|
||||
@ -7073,7 +7082,7 @@ TAKEOVER_FN(_r45_r1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _raid145_raid4510(lv, new_segtype, yes, force, 2, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid145_raid4510(lv, new_segtype, yes, force, 2, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid4 <-> raid5_n */
|
||||
@ -7141,7 +7150,7 @@ TAKEOVER_FN(_r45_r6)
|
||||
return_0;
|
||||
}
|
||||
|
||||
return _raid145_raid1_raid6(lv, new_segtype, yes, force, seg->area_count + 1, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _raid145_raid1_raid6(lv, new_segtype, yes, force, seg->area_count + 1, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid6 -> striped */
|
||||
@ -7149,7 +7158,7 @@ TAKEOVER_FN(_r6_s)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid6 -> raid0 */
|
||||
@ -7157,7 +7166,7 @@ TAKEOVER_FN(_r6_r0)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid6 -> raid0_meta */
|
||||
@ -7165,7 +7174,7 @@ TAKEOVER_FN(_r6_r0m)
|
||||
{
|
||||
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
|
||||
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2, 0 /* data_copies */, 0, 0, allocate_pvs);
|
||||
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2, 1 /* data_copies */, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
/* raid6* -> raid4/5* */
|
||||
@ -7210,13 +7219,7 @@ TAKEOVER_FN(_r6_r45)
|
||||
if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, &removal_lvs))
|
||||
return 0;
|
||||
|
||||
if (segtype_is_raid4(new_segtype))
|
||||
seg->segtype = new_segtype;
|
||||
|
||||
else if(!(seg->segtype = get_segtype_from_flag(lv->vg->cmd, _raid_seg_flag_6_to_5(seg)))) {
|
||||
log_error(INTERNAL_ERROR "Failed to get raid6 -> raid5 conversion type");
|
||||
return_0;
|
||||
}
|
||||
seg->segtype = new_segtype;
|
||||
|
||||
return _lv_update_and_reload_origin_eliminate_lvs(lv, &removal_lvs);
|
||||
}
|
||||
@ -7244,7 +7247,7 @@ PFL();
|
||||
|
||||
dm_list_init(&removal_lvs);
|
||||
|
||||
return _raid10_striped_r0(lv, new_segtype, yes, 0, 0, 0 /* data_copies */, 0, 0, allocate_pvs, &removal_lvs);
|
||||
return _raid10_striped_r0(lv, new_segtype, yes, 0, 0, 1 /* data_copies */, 0, 0, allocate_pvs, &removal_lvs);
|
||||
}
|
||||
|
||||
/* raid10 with 2 images -> mirror */
|
||||
@ -7290,7 +7293,7 @@ TAKEOVER_FN(_r10_r0)
|
||||
|
||||
dm_list_init(&removal_lvs);
|
||||
|
||||
return _raid10_striped_r0(lv, new_segtype, yes, 0, 0, 0 /* data_copies */, 0, 0, allocate_pvs, &removal_lvs);
|
||||
return _raid10_striped_r0(lv, new_segtype, yes, 0, 0, 1 /* data_copies */, 0, 0, allocate_pvs, &removal_lvs);
|
||||
}
|
||||
|
||||
/* raid10 -> raid0_meta */
|
||||
@ -7302,7 +7305,7 @@ TAKEOVER_FN(_r10_r0m)
|
||||
|
||||
dm_list_init(&removal_lvs);
|
||||
|
||||
return _raid10_striped_r0(lv, new_segtype, yes, 0, 0, 0 /* data_copies */, 0, 0, allocate_pvs, &removal_lvs);
|
||||
return _raid10_striped_r0(lv, new_segtype, yes, 0, 0, 1 /* data_copies */, 0, 0, allocate_pvs, &removal_lvs);
|
||||
}
|
||||
|
||||
/* raid10 with 2 images -> raid1 */
|
||||
@ -7586,75 +7589,99 @@ static int _log_prohibited_option(const struct lv_segment *seg_from,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _conversion_options_allowed(const struct lv_segment *seg_from,
|
||||
const struct segment_type *segtype_to,
|
||||
uint32_t new_image_count,
|
||||
int data_copies, int region_size,
|
||||
int stripes, int stripe_size)
|
||||
/* Set segtype conveniently for raid4 <-> raid5 <-> raid6 takeover */
|
||||
static int _set_convenient_raid456_segtype_to(const struct lv_segment *seg_from,
|
||||
struct segment_type **segtype)
|
||||
{
|
||||
int r = 1;
|
||||
uint32_t opts;
|
||||
const struct segment_type *new_segtype;
|
||||
uint64_t seg_flag;
|
||||
struct cmd_context *cmd;
|
||||
struct segment_type *requested_segtype;
|
||||
|
||||
RETURN_IF_ZERO(seg_from, "segment from argument");
|
||||
RETURN_IF_ZERO(segtype_to, "segment type argument");
|
||||
RETURN_IF_ZERO(segtype || *segtype, "segment type argument");
|
||||
|
||||
cmd = seg_from->lv->vg->cmd;
|
||||
new_segtype = segtype_to;
|
||||
|
||||
requested_segtype = *segtype;
|
||||
PFL();
|
||||
if (seg_is_striped(seg_from) ||
|
||||
seg_is_any_raid0(seg_from) ||
|
||||
seg_is_raid4(seg_from)) {
|
||||
PFL();
|
||||
/* If this is any raid5 conversion request -> enforce raid5_n, because we convert from striped */
|
||||
if (segtype_is_any_raid5(new_segtype) &&
|
||||
!segtype_is_raid5_n(new_segtype) &&
|
||||
!(new_segtype = get_segtype_from_flag(cmd, SEG_RAID5_N))) {
|
||||
if (segtype_is_any_raid5(*segtype) &&
|
||||
!segtype_is_raid5_n(*segtype) &&
|
||||
!(*segtype = get_segtype_from_flag(cmd, SEG_RAID5_N))) {
|
||||
log_error(INTERNAL_ERROR "Failed to get raid5_n segtype!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If this is any raid6 conversion request -> enforce raid6_n_6, because we convert from striped */
|
||||
if (segtype_is_any_raid6(new_segtype) &&
|
||||
!segtype_is_raid6_n_6(new_segtype) &&
|
||||
!(new_segtype = get_segtype_from_flag(cmd, SEG_RAID6_N_6))) {
|
||||
} else if (segtype_is_any_raid6(*segtype) &&
|
||||
!segtype_is_raid6_n_6(*segtype) &&
|
||||
!(*segtype = get_segtype_from_flag(cmd, SEG_RAID6_N_6))) {
|
||||
log_error(INTERNAL_ERROR "Failed to get raid6_n_6 segtype!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Got to do check for raid5 -> raid6 ... */
|
||||
} else if (seg_is_any_raid5(seg_from) &&
|
||||
segtype_is_any_raid6(new_segtype) &&
|
||||
!(new_segtype = get_segtype_from_flag(cmd, _raid_seg_flag_5_to_6(seg_from)))) {
|
||||
segtype_is_any_raid6(*segtype) &&
|
||||
(!(seg_flag = _raid_seg_flag_5_to_6(seg_from)) ||
|
||||
!(*segtype = get_segtype_from_flag(cmd, seg_flag)))) {
|
||||
log_error(INTERNAL_ERROR "Failed to get raid5 -> raid6 conversion type");
|
||||
return_0;
|
||||
|
||||
/* ... and raid6 -> raid5 */
|
||||
} else if (seg_is_any_raid6(seg_from) &&
|
||||
segtype_is_any_raid5(new_segtype) &&
|
||||
!(new_segtype = get_segtype_from_flag(cmd, _raid_seg_flag_6_to_5(seg_from)))) {
|
||||
segtype_is_any_raid5(*segtype) &&
|
||||
(!(seg_flag = _raid_seg_flag_6_to_5(seg_from)) ||
|
||||
!(*segtype = get_segtype_from_flag(cmd, seg_flag)))) {
|
||||
log_error(INTERNAL_ERROR "Failed to get raid6 -> raid5 conversion type");
|
||||
return_0;
|
||||
}
|
||||
|
||||
if (!_get_allowed_conversion_options(seg_from, new_segtype, new_image_count, &opts))
|
||||
return 0;
|
||||
if (requested_segtype != *segtype)
|
||||
log_warn("Replaced requested segment type %s with %s for LV %s to allow for takeover",
|
||||
requested_segtype->name, (*segtype)->name, display_lvname(seg_from->lv));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (data_copies && !(opts & ALLOW_DATA_COPIES)) {
|
||||
if (!_log_prohibited_option(seg_from, new_segtype, "-m/--mirrors"))
|
||||
/* Check allowed conversion from @seg_from to @segtype_to */
|
||||
static int _conversion_options_allowed(const struct lv_segment *seg_from,
|
||||
struct segment_type **segtype_to,
|
||||
uint32_t new_image_count,
|
||||
int data_copies, int region_size,
|
||||
int stripes, int stripe_size)
|
||||
{
|
||||
int r = 1;
|
||||
uint32_t opts;
|
||||
|
||||
RETURN_IF_ZERO(seg_from, "segment from argument");
|
||||
RETURN_IF_ZERO(segtype_to || *segtype_to, "segment type to argument");
|
||||
PFL();
|
||||
if (!_set_convenient_raid456_segtype_to(seg_from, segtype_to))
|
||||
return 0;
|
||||
PFLA("seg_from->segtype=%s segtype_to=%s", lvseg_name(seg_from), (*segtype_to)->name);
|
||||
|
||||
if (!_get_allowed_conversion_options(seg_from, *segtype_to, new_image_count, &opts))
|
||||
return 0;
|
||||
PFLA("segtype_to=%s", (*segtype_to)->name);
|
||||
|
||||
if (data_copies > 1 && !(opts & ALLOW_DATA_COPIES)) {
|
||||
if (!_log_prohibited_option(seg_from, *segtype_to, "-m/--mirrors"))
|
||||
return 0;
|
||||
|
||||
r = 0;
|
||||
}
|
||||
|
||||
if (stripes && !(opts & ALLOW_STRIPES)) {
|
||||
if (!_log_prohibited_option(seg_from, new_segtype, "--stripes"))
|
||||
if (!_log_prohibited_option(seg_from, *segtype_to, "--stripes"))
|
||||
return 0;
|
||||
r = 0;
|
||||
}
|
||||
|
||||
if (stripe_size && !(opts & ALLOW_STRIPE_SIZE)) {
|
||||
if (!_log_prohibited_option(seg_from, new_segtype, "-I/--stripesize"))
|
||||
if (!_log_prohibited_option(seg_from, *segtype_to, "-I/--stripesize"))
|
||||
return 0;
|
||||
r = 0;
|
||||
}
|
||||
@ -7716,10 +7743,10 @@ static int _conversion_options_allowed(const struct lv_segment *seg_from,
|
||||
* in order to avoid bio_endio in the targets map method?
|
||||
*/
|
||||
int lv_raid_convert(struct logical_volume *lv,
|
||||
const struct segment_type *new_segtype,
|
||||
struct segment_type *new_segtype,
|
||||
int yes, int force,
|
||||
int duplicate, int unduplicate,
|
||||
const int new_data_copies,
|
||||
const int new_data_copies, /* to be able to detect -m0; -1 if not set */
|
||||
const unsigned new_region_size,
|
||||
const unsigned new_stripes,
|
||||
const unsigned new_stripe_size,
|
||||
@ -7728,16 +7755,15 @@ int lv_raid_convert(struct logical_volume *lv,
|
||||
{
|
||||
uint32_t image_count, data_copies, region_size, stripes, stripe_size;
|
||||
struct lv_segment *seg;
|
||||
struct segment_type *new_segtype_tmp = (struct segment_type *) new_segtype;;
|
||||
struct segment_type *striped_segtype;
|
||||
struct dm_list removal_lvs;
|
||||
takeover_fn_t tfn;
|
||||
|
||||
RETURN_IF_ZERO(lv, "lv argument");
|
||||
/* new_segtype may be NULL */
|
||||
/* new_segtype may be NAUGHT */
|
||||
RETURN_IF_ZERO((seg = first_seg(lv)), "lv segment");
|
||||
|
||||
dm_list_init(&removal_lvs);
|
||||
seg = first_seg(lv);
|
||||
|
||||
if (duplicate && unduplicate) {
|
||||
log_error("--duplicate and --unduplicate are mutually exclusive!");
|
||||
@ -7750,7 +7776,28 @@ int lv_raid_convert(struct logical_volume *lv,
|
||||
}
|
||||
|
||||
if (!unduplicate) {
|
||||
new_segtype = new_segtype ?: seg->segtype;
|
||||
PFL();
|
||||
/* If we don't unduplicate, define new_segtype if not passed in */
|
||||
if (!new_segtype) {
|
||||
struct lv_segment *seg1;
|
||||
|
||||
if (_lv_is_duplicating(lv)) {
|
||||
RETURN_IF_ZERO(seg_type(seg, 0) == AREA_LV &&
|
||||
seg_lv(seg, 0) &&
|
||||
first_seg(seg_lv(seg, 0)),
|
||||
"sub lv #0");
|
||||
PFL();
|
||||
seg1 = first_seg(seg_lv(seg, 0));
|
||||
} else
|
||||
seg1 = seg;
|
||||
|
||||
new_segtype = (struct segment_type *) seg1->segtype;
|
||||
#if 0
|
||||
stripes = new_stripes ?: _data_rimages_count(seg1, seg1->area_count);
|
||||
stripe_size = new_stripe_size ?: seg1->stripe_size;
|
||||
data_copies = new_data_copies > -1 ? new_data_copies : seg1->data_copies;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!(striped_segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_STRIPED)))
|
||||
return_0;
|
||||
@ -7774,9 +7821,10 @@ PFLA("new_segtype=%s segtype=%s, seg->area_count=%u", new_segtype ? new_segtype-
|
||||
|
||||
/* Define if not passed in */
|
||||
region_size = new_region_size ?: seg->region_size;
|
||||
data_copies = new_data_copies > -1 ? new_data_copies + 1 : seg->data_copies;
|
||||
data_copies = new_data_copies > -1 ? new_data_copies : seg->data_copies;
|
||||
|
||||
if (!seg_is_linear(seg) &&
|
||||
if (new_segtype &&
|
||||
!seg_is_linear(seg) &&
|
||||
(segtype_is_striped(new_segtype) ||
|
||||
segtype_is_striped_raid(new_segtype))) {
|
||||
stripes = new_stripes ?: _data_rimages_count(seg, seg->area_count);
|
||||
@ -7828,8 +7876,22 @@ PFLA("new_segtype=%s image_count=%u data_copies=%u stripes=%u", new_segtype ? ne
|
||||
*/
|
||||
if (unduplicate) {
|
||||
if (_lv_is_duplicating(lv)) {
|
||||
if (new_segtype) {
|
||||
stripes = new_stripes;
|
||||
stripe_size = new_stripe_size;
|
||||
data_copies = new_data_copies > -1 ? new_data_copies : 1;
|
||||
|
||||
} else {
|
||||
struct lv_segment *sseg = first_seg(seg_lv(seg, 0));
|
||||
|
||||
new_segtype = (struct segment_type *) sseg->segtype;
|
||||
stripes = new_stripes ?: _data_rimages_count(sseg, sseg->area_count);
|
||||
stripe_size = new_stripe_size ?: sseg->stripe_size;
|
||||
data_copies = new_data_copies > -1 ? new_data_copies : sseg->data_copies;
|
||||
}
|
||||
|
||||
if (!_raid_conv_unduplicate(lv, new_segtype,
|
||||
new_stripes, new_stripe_size, data_copies, yes)) {
|
||||
stripes, stripe_size, data_copies, yes)) {
|
||||
if (!_lv_is_duplicating(lv))
|
||||
_log_possible_conversion_types(lv, new_segtype);
|
||||
|
||||
@ -7848,9 +7910,9 @@ PFLA("new_segtype=%s image_count=%u data_copies=%u stripes=%u", new_segtype ? ne
|
||||
*
|
||||
* reshape of capable raid type requested
|
||||
*/
|
||||
new_segtype = new_segtype ?: seg->segtype;
|
||||
new_segtype = new_segtype ?: (struct segment_type *) seg->segtype;
|
||||
|
||||
switch (_reshape_requested(lv, new_segtype_tmp ?: seg->segtype, new_stripes, new_stripe_size)) {
|
||||
switch (_reshape_requested(lv, new_segtype, new_stripes, new_stripe_size)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
@ -7885,7 +7947,7 @@ PFLA("yes=%d new_segtype=%s data_copies=%u stripes=%u stripe_size=%u", yes, new_
|
||||
*/
|
||||
if (duplicate) {
|
||||
/* Check valid options mirrors, stripes and/or stripe_size have been provided suitable to the conversion */
|
||||
if (!_conversion_options_allowed(seg, new_segtype, image_count /* duplicate check for image_count > 0 */,
|
||||
if (!_conversion_options_allowed(seg, &new_segtype, image_count /* duplicate check for image_count > 0 */,
|
||||
new_data_copies, new_region_size,
|
||||
new_stripes, new_stripe_size))
|
||||
return _log_possible_conversion_types(lv, new_segtype);
|
||||
@ -7909,7 +7971,7 @@ PFLA("yes=%d new_segtype=%s data_copies=%u stripes=%u stripe_size=%u", yes, new_
|
||||
* Check acceptible options mirrors, region_size,
|
||||
* stripes and/or stripe_size have been provided.
|
||||
*/
|
||||
if (!_conversion_options_allowed(seg, new_segtype, 0 /* Takeover */,
|
||||
if (!_conversion_options_allowed(seg, &new_segtype, 0 /* Takeover */,
|
||||
data_copies, new_region_size,
|
||||
new_stripes, new_stripe_size))
|
||||
return _log_possible_conversion_types(lv, new_segtype);
|
||||
@ -7929,7 +7991,7 @@ err:
|
||||
/* FIXME: enhance message */
|
||||
log_error("Converting the segment type for %s (directly) from %s to %s"
|
||||
" is not supported.", display_lvname(lv),
|
||||
lvseg_name(seg), new_segtype_tmp->name);
|
||||
lvseg_name(seg), new_segtype->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -119,6 +119,7 @@ struct segment_type {
|
||||
|
||||
struct segtype_handler *ops;
|
||||
const char *name;
|
||||
const char *descr;
|
||||
|
||||
void *library; /* lvm_register_segtype() sets this. */
|
||||
void *private; /* For the segtype handler to use. */
|
||||
|
@ -494,31 +494,32 @@ static const struct raid_type {
|
||||
const char name[19];
|
||||
unsigned parity;
|
||||
uint64_t extra_flags;
|
||||
const char *descr; /* HM FIXME: use segtype flags instead and display based on them */
|
||||
} _raid_types[] = {
|
||||
{ SEG_TYPE_NAME_RAID0, 0, SEG_RAID0 },
|
||||
{ SEG_TYPE_NAME_RAID0_META, 0, SEG_RAID0_META },
|
||||
{ SEG_TYPE_NAME_RAID1, 0, SEG_RAID1 | SEG_AREAS_MIRRORED },
|
||||
{ SEG_TYPE_NAME_RAID0, 0, SEG_RAID0, "striped/raid4/raid5/raid6" },
|
||||
{ SEG_TYPE_NAME_RAID0_META, 0, SEG_RAID0_META, "striped/raid4/raid5/raid6" },
|
||||
{ SEG_TYPE_NAME_RAID1, 0, SEG_RAID1 | SEG_AREAS_MIRRORED, "linear/raid4(2)/raid5(2)/raid10" },
|
||||
{ SEG_TYPE_NAME_RAID01, 0, SEG_RAID01 | SEG_AREAS_MIRRORED },
|
||||
{ SEG_TYPE_NAME_RAID10_NEAR, 0, SEG_RAID10_NEAR | SEG_AREAS_MIRRORED },
|
||||
{ SEG_TYPE_NAME_RAID10_FAR, 0, SEG_RAID10_FAR | SEG_AREAS_MIRRORED | SEG_CAN_SPLIT },
|
||||
{ SEG_TYPE_NAME_RAID10_NEAR, 0, SEG_RAID10_NEAR | SEG_AREAS_MIRRORED, "raid1?" },
|
||||
{ SEG_TYPE_NAME_RAID10_FAR, 0, SEG_RAID10_FAR | SEG_AREAS_MIRRORED | SEG_CAN_SPLIT, "striped/raid0" },
|
||||
{ SEG_TYPE_NAME_RAID10_OFFSET, 0, SEG_RAID10_OFFSET | SEG_AREAS_MIRRORED },
|
||||
{ SEG_TYPE_NAME_RAID10, 0, SEG_RAID10 | SEG_AREAS_MIRRORED }, /* is raid10_near" */
|
||||
{ SEG_TYPE_NAME_RAID4, 1, SEG_RAID4 },
|
||||
{ SEG_TYPE_NAME_RAID5_N, 1, SEG_RAID5_N },
|
||||
{ SEG_TYPE_NAME_RAID5_LA, 1, SEG_RAID5_LA },
|
||||
{ SEG_TYPE_NAME_RAID5_LS, 1, SEG_RAID5_LS },
|
||||
{ SEG_TYPE_NAME_RAID5_RA, 1, SEG_RAID5_RA },
|
||||
{ SEG_TYPE_NAME_RAID5_RS, 1, SEG_RAID5_RS },
|
||||
{ SEG_TYPE_NAME_RAID5, 1, SEG_RAID5 }, /* is raid5_ls */
|
||||
{ SEG_TYPE_NAME_RAID6_NC, 2, SEG_RAID6_NC },
|
||||
{ SEG_TYPE_NAME_RAID6_NR, 2, SEG_RAID6_NR },
|
||||
{ SEG_TYPE_NAME_RAID6_ZR, 2, SEG_RAID6_ZR },
|
||||
{ SEG_TYPE_NAME_RAID6_LA_6, 2, SEG_RAID6_LA_6 },
|
||||
{ SEG_TYPE_NAME_RAID6_LS_6, 2, SEG_RAID6_LS_6 },
|
||||
{ SEG_TYPE_NAME_RAID6_RA_6, 2, SEG_RAID6_RA_6 },
|
||||
{ SEG_TYPE_NAME_RAID6_RS_6, 2, SEG_RAID6_RS_6 },
|
||||
{ SEG_TYPE_NAME_RAID6_N_6, 2, SEG_RAID6_N_6 },
|
||||
{ SEG_TYPE_NAME_RAID6, 2, SEG_RAID6 }, /* is raid6_zr */
|
||||
{ SEG_TYPE_NAME_RAID10, 0, SEG_RAID10 | SEG_AREAS_MIRRORED /* is raid10_near */, "raid1(!(stripes%mirrors)" },
|
||||
{ SEG_TYPE_NAME_RAID4, 1, SEG_RAID4, "striped/raid0*/raid5/raid6" },
|
||||
{ SEG_TYPE_NAME_RAID5_N, 1, SEG_RAID5_N, "raid0/striped/raid4/raid6" },
|
||||
{ SEG_TYPE_NAME_RAID5_LA, 1, SEG_RAID5_LA, "raid5*/raid6" },
|
||||
{ SEG_TYPE_NAME_RAID5_LS, 1, SEG_RAID5_LS, "raid5*/raid6" },
|
||||
{ SEG_TYPE_NAME_RAID5_RA, 1, SEG_RAID5_RA, "raid5*/raid6" },
|
||||
{ SEG_TYPE_NAME_RAID5_RS, 1, SEG_RAID5_RS, "raid5*/raid6" },
|
||||
{ SEG_TYPE_NAME_RAID5, 1, SEG_RAID5 /* is raid5_ls */, "raid5*/raid6" },
|
||||
{ SEG_TYPE_NAME_RAID6_NC, 2, SEG_RAID6_NC, "raid6*" },
|
||||
{ SEG_TYPE_NAME_RAID6_NR, 2, SEG_RAID6_NR, "raid6*" },
|
||||
{ SEG_TYPE_NAME_RAID6_ZR, 2, SEG_RAID6_ZR, "raid6*" },
|
||||
{ SEG_TYPE_NAME_RAID6_LA_6, 2, SEG_RAID6_LA_6, "raid5/raid6*" },
|
||||
{ SEG_TYPE_NAME_RAID6_LS_6, 2, SEG_RAID6_LS_6, "raid5/raid6*" },
|
||||
{ SEG_TYPE_NAME_RAID6_RA_6, 2, SEG_RAID6_RA_6, "raid5/raid6*" },
|
||||
{ SEG_TYPE_NAME_RAID6_RS_6, 2, SEG_RAID6_RS_6, "raid5/raid6*" },
|
||||
{ SEG_TYPE_NAME_RAID6_N_6, 2, SEG_RAID6_N_6, "striped/raid0*/raid5/raid6*" },
|
||||
{ SEG_TYPE_NAME_RAID6, 2, SEG_RAID6 /* is raid6_zr */, "raid6*" },
|
||||
};
|
||||
|
||||
static struct segment_type *_init_raid_segtype(struct cmd_context *cmd,
|
||||
@ -535,6 +536,7 @@ static struct segment_type *_init_raid_segtype(struct cmd_context *cmd,
|
||||
|
||||
segtype->ops = &_raid_ops;
|
||||
segtype->name = rt->name;
|
||||
segtype->descr = rt->descr ?: "";
|
||||
segtype->flags = SEG_RAID | SEG_ONLY_EXCLUSIVE | rt->extra_flags | monitored;
|
||||
segtype->parity_devs = rt->parity;
|
||||
|
||||
|
@ -1703,8 +1703,7 @@ static void _lvconvert_raid_repair_ask(struct cmd_context *cmd,
|
||||
|
||||
static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *lp)
|
||||
{
|
||||
int replace = 0, image_count = 0;
|
||||
uint32_t data_copies;
|
||||
int data_copies, image_count = 0, replace = 0;
|
||||
struct dm_list *failed_pvs;
|
||||
struct cmd_context *cmd = lv->vg->cmd;
|
||||
struct lv_segment *seg = first_seg(lv);
|
||||
@ -1761,6 +1760,7 @@ PFLA("image_count=%u\n", image_count);
|
||||
arg_is_set(cmd, mirrors_ARG) ||
|
||||
arg_is_set(cmd, stripes_long_ARG) ||
|
||||
arg_is_set(cmd, stripesize_ARG) ||
|
||||
arg_is_set(cmd, duplicate_ARG) ||
|
||||
arg_is_set(cmd, unduplicate_ARG))) {
|
||||
unsigned stripes = 0;
|
||||
unsigned stripe_size = arg_count(cmd, stripesize_ARG) ? lp->stripe_size : 0;
|
||||
@ -1813,12 +1813,16 @@ PFLA("image_count=%u\n", image_count);
|
||||
}
|
||||
data_copies = stripes = 1;
|
||||
stripe_size = 0;
|
||||
}
|
||||
|
||||
return lv_raid_convert(lv, arg_count(cmd, type_ARG) ? lp->segtype : NULL, lp->yes, lp->force,
|
||||
} else
|
||||
data_copies = arg_is_set(cmd, mirrors_ARG) ? lp->mirrors : -1;
|
||||
|
||||
return lv_raid_convert(lv, arg_count(cmd, type_ARG) ? (struct segment_type *) lp->segtype : NULL,
|
||||
lp->yes, lp->force,
|
||||
arg_is_set(cmd, duplicate_ARG), arg_is_set(cmd, unduplicate_ARG),
|
||||
arg_is_set(cmd, mirrors_ARG) ? lp->mirrors : -1, lp->region_size,
|
||||
stripes, stripe_size, lp->pool_data_name, lp->pvh);
|
||||
data_copies, lp->region_size,
|
||||
stripes, stripe_size,
|
||||
lp->pool_data_name, lp->pvh);
|
||||
}
|
||||
|
||||
if (arg_count(cmd, replace_ARG))
|
||||
|
Loading…
x
Reference in New Issue
Block a user