1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

move removable_pvs checking

This commit is contained in:
Alasdair Kergon 2008-01-16 19:11:39 +00:00
parent 7d18ea22eb
commit e344497277

View File

@ -335,6 +335,39 @@ static void _remove_mirror_log(struct lv_segment *mirrored_seg)
remove_seg_from_segs_using_this_lv(log_lv, mirrored_seg);
}
/* Check if mirror image LV is removable with regard to given removable_pvs */
static int _is_mirror_image_removable(struct logical_volume *mimage_lv,
struct list *removable_pvs)
{
struct physical_volume *pv;
struct lv_segment *seg;
int pv_found;
struct pv_list *pvl;
uint32_t s;
list_iterate_items(seg, &mimage_lv->segments) {
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_PV)
/* FIXME Recurse for AREA_LV */
continue;
pv = seg_pv(seg, s);
pv_found = 0;
list_iterate_items(pvl, removable_pvs) {
if (pv->dev->dev == pvl->pv->dev->dev) {
pv_found = 1;
break;
}
}
if (!pv_found)
return 0;
}
}
return 1;
}
/*
* Remove num_removed images from mirrored_seg
*/
@ -344,15 +377,12 @@ static int _remove_mirror_images(struct logical_volume *lv,
unsigned remove_log, unsigned collapse)
{
uint32_t m;
uint32_t s, s1;
uint32_t s;
struct logical_volume *sub_lv;
struct logical_volume *log_lv = NULL;
struct logical_volume *lv1 = NULL;
struct physical_volume *pv;
struct lv_segment *seg, *mirrored_seg = first_seg(lv);
struct lv_segment *mirrored_seg = first_seg(lv);
struct lv_segment_area area;
int all_pvs_removable, pv_found;
struct pv_list *pvl;
uint32_t old_area_count = mirrored_seg->area_count;
uint32_t new_area_count = mirrored_seg->area_count;
struct lv_list *lvl;
@ -373,32 +403,8 @@ static int _remove_mirror_images(struct logical_volume *lv,
if (removable_pvs) {
for (s = 0; s < mirrored_seg->area_count &&
old_area_count - new_area_count < num_removed; s++) {
all_pvs_removable = 1;
sub_lv = seg_lv(mirrored_seg, s);
list_iterate_items(seg, &sub_lv->segments) {
for (s1 = 0; s1 < seg->area_count; s1++) {
if (seg_type(seg, s1) != AREA_PV)
/* FIXME Recurse for AREA_LV */
continue;
pv = seg_pv(seg, s1);
pv_found = 0;
list_iterate_items(pvl, removable_pvs) {
if (pv->dev->dev == pvl->pv->dev->dev) {
pv_found = 1;
break;
}
}
if (!pv_found) {
all_pvs_removable = 0;
break;
}
}
if (!all_pvs_removable)
break;
}
if (all_pvs_removable) {
if (_is_mirror_image_removable(sub_lv, removable_pvs)) {
/* Swap segment to end */
new_area_count--;
area = mirrored_seg->areas[new_area_count];