mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-17 06:04:23 +03:00
Fix pvmove allocation to take existing parallel stripes into account.
When moving parts of striped LVs, pvmove wouldn't care about leaving you with two stripes on the same disk. Now --alloc anywhere is needed for that. (Tried and gave up on two alternative approaches before the one committed here.)
This commit is contained in:
parent
18e0f9342d
commit
aab7a3978b
@ -1,5 +1,7 @@
|
|||||||
Version 2.02.63 -
|
Version 2.02.63 -
|
||||||
================================
|
================================
|
||||||
|
Fix pvmove allocation to take existing parallel stripes into account.
|
||||||
|
Add pvmove_source_seg to struct lv_segment.
|
||||||
Fix incorrect removal of symlinks after LV deactivation fails.
|
Fix incorrect removal of symlinks after LV deactivation fails.
|
||||||
Fix is_partitioned_dev not to attempt to reopen device.
|
Fix is_partitioned_dev not to attempt to reopen device.
|
||||||
Fix another thread race in clvmd.
|
Fix another thread race in clvmd.
|
||||||
|
@ -219,7 +219,7 @@ static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm)
|
|||||||
len = _area_length(lvm, le);
|
len = _area_length(lvm, le);
|
||||||
|
|
||||||
if (!(seg = alloc_lv_segment(cmd->mem, segtype, lvm->lv, le,
|
if (!(seg = alloc_lv_segment(cmd->mem, segtype, lvm->lv, le,
|
||||||
len, 0, 0, NULL, 1, len, 0, 0, 0))) {
|
len, 0, 0, NULL, 1, len, 0, 0, 0, NULL))) {
|
||||||
log_error("Failed to allocate linear segment.");
|
log_error("Failed to allocate linear segment.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -293,7 +293,7 @@ static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm)
|
|||||||
lvm->stripes * area_len,
|
lvm->stripes * area_len,
|
||||||
0, lvm->stripe_size, NULL,
|
0, lvm->stripe_size, NULL,
|
||||||
lvm->stripes,
|
lvm->stripes,
|
||||||
area_len, 0, 0, 0))) {
|
area_len, 0, 0, 0, NULL))) {
|
||||||
log_error("Failed to allocate striped segment.");
|
log_error("Failed to allocate striped segment.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ static int _add_stripe_seg(struct dm_pool *mem,
|
|||||||
if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
|
if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
|
||||||
area_len * usp->num_devs, 0,
|
area_len * usp->num_devs, 0,
|
||||||
usp->striping, NULL, usp->num_devs,
|
usp->striping, NULL, usp->num_devs,
|
||||||
area_len, 0, 0, 0))) {
|
area_len, 0, 0, 0, NULL))) {
|
||||||
log_error("Unable to allocate striped lv_segment structure");
|
log_error("Unable to allocate striped lv_segment structure");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ static int _add_linear_seg(struct dm_pool *mem,
|
|||||||
if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
|
if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
|
||||||
area_len, 0, usp->striping,
|
area_len, 0, usp->striping,
|
||||||
NULL, 1, area_len,
|
NULL, 1, area_len,
|
||||||
POOL_PE_SIZE, 0, 0))) {
|
POOL_PE_SIZE, 0, 0, NULL))) {
|
||||||
log_error("Unable to allocate linear lv_segment "
|
log_error("Unable to allocate linear lv_segment "
|
||||||
"structure");
|
"structure");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -340,7 +340,7 @@ static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
|
|||||||
|
|
||||||
if (!(seg = alloc_lv_segment(mem, segtype, lv, start_extent,
|
if (!(seg = alloc_lv_segment(mem, segtype, lv, start_extent,
|
||||||
extent_count, 0, 0, NULL, area_count,
|
extent_count, 0, 0, NULL, area_count,
|
||||||
extent_count, 0, 0, 0))) {
|
extent_count, 0, 0, 0, NULL))) {
|
||||||
log_error("Segment allocation failed");
|
log_error("Segment allocation failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,8 @@ struct lv_segment *alloc_lv_segment(struct dm_pool *mem,
|
|||||||
uint32_t area_len,
|
uint32_t area_len,
|
||||||
uint32_t chunk_size,
|
uint32_t chunk_size,
|
||||||
uint32_t region_size,
|
uint32_t region_size,
|
||||||
uint32_t extents_copied);
|
uint32_t extents_copied,
|
||||||
|
struct lv_segment *pvmove_source_seg);
|
||||||
|
|
||||||
struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
|
struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
|
||||||
uint64_t status, uint32_t old_le_count);
|
uint64_t status, uint32_t old_le_count);
|
||||||
@ -76,6 +77,7 @@ int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
|
|||||||
void alloc_destroy(struct alloc_handle *ah);
|
void alloc_destroy(struct alloc_handle *ah);
|
||||||
|
|
||||||
struct dm_list *build_parallel_areas_from_lv(struct cmd_context *cmd,
|
struct dm_list *build_parallel_areas_from_lv(struct cmd_context *cmd,
|
||||||
struct logical_volume *lv);
|
struct logical_volume *lv,
|
||||||
|
unsigned use_pvmove_parent_lv);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -174,7 +174,8 @@ struct lv_segment *alloc_lv_segment(struct dm_pool *mem,
|
|||||||
uint32_t area_len,
|
uint32_t area_len,
|
||||||
uint32_t chunk_size,
|
uint32_t chunk_size,
|
||||||
uint32_t region_size,
|
uint32_t region_size,
|
||||||
uint32_t extents_copied)
|
uint32_t extents_copied,
|
||||||
|
struct lv_segment *pvmove_source_seg)
|
||||||
{
|
{
|
||||||
struct lv_segment *seg;
|
struct lv_segment *seg;
|
||||||
uint32_t areas_sz = area_count * sizeof(*seg->areas);
|
uint32_t areas_sz = area_count * sizeof(*seg->areas);
|
||||||
@ -204,6 +205,7 @@ struct lv_segment *alloc_lv_segment(struct dm_pool *mem,
|
|||||||
seg->region_size = region_size;
|
seg->region_size = region_size;
|
||||||
seg->extents_copied = extents_copied;
|
seg->extents_copied = extents_copied;
|
||||||
seg->log_lv = log_lv;
|
seg->log_lv = log_lv;
|
||||||
|
seg->pvmove_source_seg = pvmove_source_seg;
|
||||||
dm_list_init(&seg->tags);
|
dm_list_init(&seg->tags);
|
||||||
|
|
||||||
if (log_lv && !attach_mirror_log(seg, log_lv))
|
if (log_lv && !attach_mirror_log(seg, log_lv))
|
||||||
@ -227,7 +229,7 @@ struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
|
|||||||
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv, old_le_count,
|
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv, old_le_count,
|
||||||
lv->le_count - old_le_count, status, 0,
|
lv->le_count - old_le_count, status, 0,
|
||||||
NULL, 0, lv->le_count - old_le_count,
|
NULL, 0, lv->le_count - old_le_count,
|
||||||
0, 0, 0))) {
|
0, 0, 0, NULL))) {
|
||||||
log_error("Couldn't allocate new snapshot segment.");
|
log_error("Couldn't allocate new snapshot segment.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -693,7 +695,7 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint64_t status,
|
|||||||
aa[0].len * area_multiple,
|
aa[0].len * area_multiple,
|
||||||
status, stripe_size, NULL,
|
status, stripe_size, NULL,
|
||||||
area_count,
|
area_count,
|
||||||
aa[0].len, 0u, region_size, 0u))) {
|
aa[0].len, 0u, region_size, 0u, NULL))) {
|
||||||
log_error("Couldn't allocate new LV segment.");
|
log_error("Couldn't allocate new LV segment.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -807,7 +809,8 @@ static int _alloc_parallel_area(struct alloc_handle *ah, uint32_t needed,
|
|||||||
* In the last case, this function passes on the return code.
|
* In the last case, this function passes on the return code.
|
||||||
*/
|
*/
|
||||||
static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
|
static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
uint32_t le, uint32_t len, uint32_t *max_seg_len,
|
uint32_t le, uint32_t len, struct lv_segment *seg,
|
||||||
|
uint32_t *max_seg_len,
|
||||||
uint32_t first_area, uint32_t max_areas,
|
uint32_t first_area, uint32_t max_areas,
|
||||||
int top_level_area_index,
|
int top_level_area_index,
|
||||||
int only_single_area_segments,
|
int only_single_area_segments,
|
||||||
@ -816,12 +819,11 @@ static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
void *data),
|
void *data),
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct lv_segment *seg;
|
|
||||||
uint32_t s;
|
uint32_t s;
|
||||||
uint32_t remaining_seg_len, area_len, area_multiple;
|
uint32_t remaining_seg_len, area_len, area_multiple;
|
||||||
int r = 1;
|
int r = 1;
|
||||||
|
|
||||||
if (!(seg = find_seg_by_le(lv, le))) {
|
if (!seg && !(seg = find_seg_by_le(lv, le))) {
|
||||||
log_error("Failed to find segment for %s extent %" PRIu32,
|
log_error("Failed to find segment for %s extent %" PRIu32,
|
||||||
lv->name, le);
|
lv->name, le);
|
||||||
return 0;
|
return 0;
|
||||||
@ -846,7 +848,7 @@ static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
if (!(r = _for_each_pv(cmd, seg_lv(seg, s),
|
if (!(r = _for_each_pv(cmd, seg_lv(seg, s),
|
||||||
seg_le(seg, s) +
|
seg_le(seg, s) +
|
||||||
(le - seg->le) / area_multiple,
|
(le - seg->le) / area_multiple,
|
||||||
area_len, max_seg_len,
|
area_len, NULL, max_seg_len,
|
||||||
only_single_area_segments ? 0 : 0,
|
only_single_area_segments ? 0 : 0,
|
||||||
only_single_area_segments ? 1U : 0U,
|
only_single_area_segments ? 1U : 0U,
|
||||||
top_level_area_index != -1 ? top_level_area_index : (int) s,
|
top_level_area_index != -1 ? top_level_area_index : (int) s,
|
||||||
@ -862,7 +864,7 @@ static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
|
|
||||||
/* FIXME only_single_area_segments used as workaround to skip log LV - needs new param? */
|
/* FIXME only_single_area_segments used as workaround to skip log LV - needs new param? */
|
||||||
if (!only_single_area_segments && seg_is_mirrored(seg) && seg->log_lv) {
|
if (!only_single_area_segments && seg_is_mirrored(seg) && seg->log_lv) {
|
||||||
if (!(r = _for_each_pv(cmd, seg->log_lv, 0, seg->log_lv->le_count,
|
if (!(r = _for_each_pv(cmd, seg->log_lv, 0, seg->log_lv->le_count, NULL,
|
||||||
NULL, 0, 0, 0, only_single_area_segments,
|
NULL, 0, 0, 0, only_single_area_segments,
|
||||||
fn, data)))
|
fn, data)))
|
||||||
stack;
|
stack;
|
||||||
@ -965,7 +967,7 @@ static int _check_cling(struct cmd_context *cmd,
|
|||||||
|
|
||||||
/* FIXME Cope with stacks by flattening */
|
/* FIXME Cope with stacks by flattening */
|
||||||
if (!(r = _for_each_pv(cmd, prev_lvseg->lv,
|
if (!(r = _for_each_pv(cmd, prev_lvseg->lv,
|
||||||
prev_lvseg->le + prev_lvseg->len - 1, 1, NULL,
|
prev_lvseg->le + prev_lvseg->len - 1, 1, NULL, NULL,
|
||||||
0, 0, -1, 1,
|
0, 0, -1, 1,
|
||||||
_is_condition, &pvmatch)))
|
_is_condition, &pvmatch)))
|
||||||
stack;
|
stack;
|
||||||
@ -993,7 +995,7 @@ static int _check_contiguous(struct cmd_context *cmd,
|
|||||||
|
|
||||||
/* FIXME Cope with stacks by flattening */
|
/* FIXME Cope with stacks by flattening */
|
||||||
if (!(r = _for_each_pv(cmd, prev_lvseg->lv,
|
if (!(r = _for_each_pv(cmd, prev_lvseg->lv,
|
||||||
prev_lvseg->le + prev_lvseg->len - 1, 1, NULL,
|
prev_lvseg->le + prev_lvseg->len - 1, 1, NULL, NULL,
|
||||||
0, 0, -1, 1,
|
0, 0, -1, 1,
|
||||||
_is_condition, &pvmatch)))
|
_is_condition, &pvmatch)))
|
||||||
stack;
|
stack;
|
||||||
@ -1364,7 +1366,7 @@ int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
|
|||||||
|
|
||||||
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
|
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
|
||||||
lv->le_count, extents, status, 0,
|
lv->le_count, extents, status, 0,
|
||||||
NULL, 0, extents, 0, 0, 0))) {
|
NULL, 0, extents, 0, 0, 0, NULL))) {
|
||||||
log_error("Couldn't allocate new zero segment.");
|
log_error("Couldn't allocate new zero segment.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1504,7 +1506,7 @@ static struct lv_segment *_convert_seg_to_mirror(struct lv_segment *seg,
|
|||||||
log_lv,
|
log_lv,
|
||||||
seg->area_count, seg->area_len,
|
seg->area_count, seg->area_len,
|
||||||
seg->chunk_size, region_size,
|
seg->chunk_size, region_size,
|
||||||
seg->extents_copied))) {
|
seg->extents_copied, NULL))) {
|
||||||
log_error("Couldn't allocate converted LV segment");
|
log_error("Couldn't allocate converted LV segment");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1513,6 +1515,8 @@ static struct lv_segment *_convert_seg_to_mirror(struct lv_segment *seg,
|
|||||||
if (!move_lv_segment_area(newseg, s, seg, s))
|
if (!move_lv_segment_area(newseg, s, seg, s))
|
||||||
return_NULL;
|
return_NULL;
|
||||||
|
|
||||||
|
seg->pvmove_source_seg = NULL; /* Not maintained after allocation */
|
||||||
|
|
||||||
dm_list_add(&seg->list, &newseg->list);
|
dm_list_add(&seg->list, &newseg->list);
|
||||||
dm_list_del(&seg->list);
|
dm_list_del(&seg->list);
|
||||||
|
|
||||||
@ -2050,13 +2054,16 @@ static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct dm_list of segments of LVs showing which PVs they use.
|
* Construct dm_list of segments of LVs showing which PVs they use.
|
||||||
|
* For pvmove we use the *parent* LV so we can pick up stripes & existing mirrors etc.
|
||||||
*/
|
*/
|
||||||
struct dm_list *build_parallel_areas_from_lv(struct cmd_context *cmd,
|
struct dm_list *build_parallel_areas_from_lv(struct cmd_context *cmd,
|
||||||
struct logical_volume *lv)
|
struct logical_volume *lv,
|
||||||
|
unsigned use_pvmove_parent_lv)
|
||||||
{
|
{
|
||||||
struct dm_list *parallel_areas;
|
struct dm_list *parallel_areas;
|
||||||
struct seg_pvs *spvs;
|
struct seg_pvs *spvs;
|
||||||
uint32_t current_le = 0;
|
uint32_t current_le = 0;
|
||||||
|
struct lv_segment *seg;
|
||||||
|
|
||||||
if (!(parallel_areas = dm_pool_alloc(cmd->mem, sizeof(*parallel_areas)))) {
|
if (!(parallel_areas = dm_pool_alloc(cmd->mem, sizeof(*parallel_areas)))) {
|
||||||
log_error("parallel_areas allocation failed");
|
log_error("parallel_areas allocation failed");
|
||||||
@ -2078,9 +2085,19 @@ struct dm_list *build_parallel_areas_from_lv(struct cmd_context *cmd,
|
|||||||
|
|
||||||
dm_list_add(parallel_areas, &spvs->list);
|
dm_list_add(parallel_areas, &spvs->list);
|
||||||
|
|
||||||
|
if (use_pvmove_parent_lv && !(seg = find_seg_by_le(lv, current_le))) {
|
||||||
|
log_error("Failed to find segment for %s extent %" PRIu32,
|
||||||
|
lv->name, current_le);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find next segment end */
|
/* Find next segment end */
|
||||||
/* FIXME Unnecessary nesting! */
|
/* FIXME Unnecessary nesting! */
|
||||||
if (!_for_each_pv(cmd, lv, current_le, spvs->len, &spvs->len,
|
if (!_for_each_pv(cmd, use_pvmove_parent_lv ? seg->pvmove_source_seg->lv : lv,
|
||||||
|
use_pvmove_parent_lv ? seg->pvmove_source_seg->le : current_le,
|
||||||
|
use_pvmove_parent_lv ? spvs->len * calc_area_multiple(seg->pvmove_source_seg->segtype, seg->pvmove_source_seg->area_count) : spvs->len,
|
||||||
|
seg->pvmove_source_seg,
|
||||||
|
&spvs->len,
|
||||||
0, 0, -1, 0, _add_pvs, (void *) spvs))
|
0, 0, -1, 0, _add_pvs, (void *) spvs))
|
||||||
return_NULL;
|
return_NULL;
|
||||||
|
|
||||||
@ -2331,7 +2348,7 @@ int split_parent_segments_for_layer(struct cmd_context *cmd,
|
|||||||
uint32_t s;
|
uint32_t s;
|
||||||
struct dm_list *parallel_areas;
|
struct dm_list *parallel_areas;
|
||||||
|
|
||||||
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, layer_lv)))
|
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, layer_lv, 0)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
/* Loop through all LVs except itself */
|
/* Loop through all LVs except itself */
|
||||||
@ -2617,7 +2634,7 @@ struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
|
|||||||
if (!(mapseg = alloc_lv_segment(cmd->mem, segtype,
|
if (!(mapseg = alloc_lv_segment(cmd->mem, segtype,
|
||||||
lv_where, 0, layer_lv->le_count,
|
lv_where, 0, layer_lv->le_count,
|
||||||
status, 0, NULL, 1, layer_lv->le_count,
|
status, 0, NULL, 1, layer_lv->le_count,
|
||||||
0, 0, 0)))
|
0, 0, 0, NULL)))
|
||||||
return_NULL;
|
return_NULL;
|
||||||
|
|
||||||
/* map the new segment to the original underlying are */
|
/* map the new segment to the original underlying are */
|
||||||
@ -2660,7 +2677,7 @@ static int _extend_layer_lv_for_segment(struct logical_volume *layer_lv,
|
|||||||
if (!(mapseg = alloc_lv_segment(layer_lv->vg->cmd->mem, segtype,
|
if (!(mapseg = alloc_lv_segment(layer_lv->vg->cmd->mem, segtype,
|
||||||
layer_lv, layer_lv->le_count,
|
layer_lv, layer_lv->le_count,
|
||||||
seg->area_len, status, 0,
|
seg->area_len, status, 0,
|
||||||
NULL, 1, seg->area_len, 0, 0, 0)))
|
NULL, 1, seg->area_len, 0, 0, 0, seg)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
/* map the new segment to the original underlying are */
|
/* map the new segment to the original underlying are */
|
||||||
|
@ -280,7 +280,7 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
|
|||||||
seg->log_lv,
|
seg->log_lv,
|
||||||
seg->area_count, seg->area_len,
|
seg->area_count, seg->area_len,
|
||||||
seg->chunk_size, seg->region_size,
|
seg->chunk_size, seg->region_size,
|
||||||
seg->extents_copied))) {
|
seg->extents_copied, seg->pvmove_source_seg))) {
|
||||||
log_error("Couldn't allocate cloned LV segment.");
|
log_error("Couldn't allocate cloned LV segment.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -301,6 +301,7 @@ struct lv_segment {
|
|||||||
uint32_t region_size; /* For mirrors - in sectors */
|
uint32_t region_size; /* For mirrors - in sectors */
|
||||||
uint32_t extents_copied;
|
uint32_t extents_copied;
|
||||||
struct logical_volume *log_lv;
|
struct logical_volume *log_lv;
|
||||||
|
struct lv_segment *pvmove_source_seg;
|
||||||
void *segtype_private;
|
void *segtype_private;
|
||||||
|
|
||||||
struct dm_list tags;
|
struct dm_list tags;
|
||||||
|
@ -1450,7 +1450,7 @@ int add_mirrors_to_segments(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
uint32_t adjusted_region_size;
|
uint32_t adjusted_region_size;
|
||||||
int r = 1;
|
int r = 1;
|
||||||
|
|
||||||
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv)))
|
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
|
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
|
||||||
@ -1702,7 +1702,7 @@ int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv)))
|
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv, 0)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
|
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
|
||||||
@ -1767,7 +1767,7 @@ int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
* allocate destination extents
|
* allocate destination extents
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv)))
|
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv, 0)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
|
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user