mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
raid_manip: prevent reshape with freed component SubLVs
In order to free SubLVs after a stripe removing reshape, lvconvert has to be run without layout changes. Prevent a layout changing request in case any such freed SubLVs exist and inform the user about the fact requesting to release them first.
This commit is contained in:
parent
cc6ddf978a
commit
d01e5ec126
@ -2272,6 +2272,21 @@ static int _pre_raid0_remove_rmeta(struct logical_volume *lv, void *data)
|
|||||||
return _activate_sub_lvs_excl_local_list(lv, lv_list) ? 2 : 0;
|
return _activate_sub_lvs_excl_local_list(lv, lv_list) ? 2 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _same_layout(struct lv_segment *seg,
|
||||||
|
const struct segment_type *new_segtype,
|
||||||
|
const unsigned new_data_copies,
|
||||||
|
const unsigned new_region_size,
|
||||||
|
const unsigned old_image_count,
|
||||||
|
const unsigned new_image_count,
|
||||||
|
const unsigned new_stripe_size)
|
||||||
|
{
|
||||||
|
return (seg->segtype == new_segtype &&
|
||||||
|
seg->data_copies == new_data_copies &&
|
||||||
|
seg->region_size == new_region_size &&
|
||||||
|
old_image_count == new_image_count &&
|
||||||
|
seg->stripe_size == new_stripe_size) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reshape logical volume @lv by adding/removing stripes
|
* Reshape logical volume @lv by adding/removing stripes
|
||||||
* (absolute new stripes given in @new_stripes), changing
|
* (absolute new stripes given in @new_stripes), changing
|
||||||
@ -2292,7 +2307,7 @@ static int _raid_reshape(struct logical_volume *lv,
|
|||||||
{
|
{
|
||||||
int force_repair = 0, r, too_few = 0;
|
int force_repair = 0, r, too_few = 0;
|
||||||
unsigned devs_health, devs_in_sync;
|
unsigned devs_health, devs_in_sync;
|
||||||
uint32_t new_image_count, old_image_count;
|
uint32_t available_slvs, removed_slvs, new_image_count, old_image_count;
|
||||||
enum alloc_where where_it_was = alloc_none;
|
enum alloc_where where_it_was = alloc_none;
|
||||||
struct lv_segment *seg = first_seg(lv);
|
struct lv_segment *seg = first_seg(lv);
|
||||||
struct dm_list removal_lvs;
|
struct dm_list removal_lvs;
|
||||||
@ -2310,7 +2325,7 @@ static int _raid_reshape(struct logical_volume *lv,
|
|||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
/* FIXME Can't reshape volume in use - aka not toplevel devices */
|
/* FIXME Can't reshape volume in use - aka not toplevel devices */
|
||||||
if (old_image_count < new_image_count &&
|
if (old_image_count != new_image_count &&
|
||||||
!dm_list_empty(&seg->lv->segs_using_this_lv)) {
|
!dm_list_empty(&seg->lv->segs_using_this_lv)) {
|
||||||
log_error("Unable to convert stacked volume %s.", display_lvname(seg->lv));
|
log_error("Unable to convert stacked volume %s.", display_lvname(seg->lv));
|
||||||
return 0;
|
return 0;
|
||||||
@ -2328,16 +2343,26 @@ static int _raid_reshape(struct logical_volume *lv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Prevent any new reshape request on RaidLV with existing freed stripes resulting from a previous one. */
|
||||||
|
if (!_get_available_removed_sublvs(lv, &available_slvs, &removed_slvs))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
if (removed_slvs &&
|
||||||
|
!_same_layout(seg, new_segtype, new_data_copies, new_region_size,
|
||||||
|
old_image_count, new_image_count + removed_slvs, new_stripe_size)) {
|
||||||
|
log_error("Unable to convert %s containing sub LVs to remove after a reshape.",
|
||||||
|
display_lvname(lv));
|
||||||
|
log_error("Run \"lvconvert --stripes %" PRIu32 " %s\" first.",
|
||||||
|
seg->area_count - removed_slvs - 1, display_lvname(lv));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
lv->status &= ~LV_RESHAPE; /* Reset any reshaping segtype flag */
|
lv->status &= ~LV_RESHAPE; /* Reset any reshaping segtype flag */
|
||||||
|
|
||||||
dm_list_init(&removal_lvs);
|
dm_list_init(&removal_lvs);
|
||||||
|
|
||||||
/* No change in layout requested ? */
|
/* No change in layout requested ? */
|
||||||
if (seg->segtype == new_segtype &&
|
if (_same_layout(seg, new_segtype, new_data_copies, new_region_size, old_image_count, new_image_count, new_stripe_size)) {
|
||||||
seg->data_copies == new_data_copies &&
|
|
||||||
seg->region_size == new_region_size &&
|
|
||||||
old_image_count == new_image_count &&
|
|
||||||
seg->stripe_size == new_stripe_size) {
|
|
||||||
/*
|
/*
|
||||||
* No change in segment type, image count, region or stripe size has been requested ->
|
* No change in segment type, image count, region or stripe size has been requested ->
|
||||||
* user requests this to remove any reshape space from the @lv
|
* user requests this to remove any reshape space from the @lv
|
||||||
|
Loading…
Reference in New Issue
Block a user