1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-11 20:58:50 +03:00

Fix mirrored stripe reduction.

Patch adds check for stripe not only in direct
LV segment but also in mirror image segment.

This prevents bugs like:

# lvcreate -i2 -l10 -n lv vg_test
# lvconvert -m1 -i1 vg_test/lv

# lvreduce -f -l1 vg_test/lv
  WARNING: Reducing active logical volume to 4.00 MiB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
  Reducing logical volume lv to 4.00 MiB
  Segment extent reduction 9 not divisible by #stripes 2
  Logical volume lv successfully resized

# lvremove -f vg_test
  Segment extent reduction 1 not divisible by #stripes 2
  LV segment lv:0-4294967295 is incorrectly listed as being used by LV lv_mimage_0
  Internal error: LV segments corrupted in lv_mimage_0.
This commit is contained in:
Milan Broz 2011-06-09 19:38:56 +00:00
parent 4fb39ae074
commit f4ba9c5d1e
3 changed files with 39 additions and 4 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.86 - Version 2.02.86 -
================================= =================================
Fix reduction of mirrors with striped segments to always align to stripe size.
Validate mirror segments size. Validate mirror segments size.
Fix extent rounding for striped volumes (never reduce more than requested). Fix extent rounding for striped volumes (never reduce more than requested).
Fix create_temp_name to replace any '/' found in the hostname with '?'. Fix create_temp_name to replace any '/' found in the hostname with '?'.

View File

@ -240,3 +240,11 @@ lvconvert -m+1 --mirrorlog disk -i1 $vg/$lv1 $dev4 $dev3:0
check mirror $vg $lv1 $dev3 check mirror $vg $lv1 $dev3
check mirror_no_temporaries $vg $lv1 check mirror_no_temporaries $vg $lv1
check mirror_legs $vg $lv1 3 check mirror_legs $vg $lv1 3
# simple mirrored stripe
aux prepare_vg 5
lvcreate -i2 -l10 -n $lv1 $vg
lvconvert -m1 -i1 $vg/$lv1
lvreduce -f -l1 $vg/$lv1
lvextend -f -l10 $vg/$lv1
lvremove -ff $vg/$lv1

View File

@ -305,6 +305,34 @@ static int _adjust_policy_params(struct cmd_context *cmd,
return 1; return 1;
} }
static uint32_t lvseg_get_stripes(struct lv_segment *seg, uint32_t *stripesize)
{
uint32_t s;
struct lv_segment *seg_mirr;
/* If segment mirrored, check if images are striped */
if (seg_is_mirrored(seg))
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_LV)
continue;
seg_mirr = first_seg(seg_lv(seg, s));
if (seg_is_striped(seg_mirr)) {
seg = seg_mirr;
break;
}
}
if (seg_is_striped(seg)) {
*stripesize = seg->stripe_size;
return seg->area_count;
}
*stripesize = 0;
return 0;
}
static int _lvresize(struct cmd_context *cmd, struct volume_group *vg, static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
struct lvresize_params *lp) struct lvresize_params *lp)
{ {
@ -548,10 +576,8 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
dm_list_iterate_items(seg, &lv->segments) { dm_list_iterate_items(seg, &lv->segments) {
seg_extents = seg->len; seg_extents = seg->len;
if (seg_is_striped(seg)) { /* Check for underlying stripe sizes */
seg_stripesize = seg->stripe_size; seg_stripes = lvseg_get_stripes(seg, &seg_stripesize);
seg_stripes = seg->area_count;
}
if (seg_is_mirrored(seg)) if (seg_is_mirrored(seg))
seg_mirrors = lv_mirror_count(seg->lv); seg_mirrors = lv_mirror_count(seg->lv);