From 2c9cf3b73bc0d655e8521d1e440592ece129aa8c Mon Sep 17 00:00:00 2001 From: Jonathan Earl Brassow Date: Wed, 14 Sep 2011 02:45:36 +0000 Subject: [PATCH] Fix for bug 734252 - problem up converting striped mirror after image failure lv_mirror_count was not able to handle mirrors of stripes properly. When a failed device is removed, the MIRRORED status flag is removed from the LV conditionally based on the results of lv_mirror_count. However, lv_mirror_count trusted the MIRRORED flag - thinking any such LV must be mirrored. It would happily assign first_seg(lv)->area_count as the number of mirrors, but when a mirrored striped LV was reduced to a simple striped LV area_count would be the number of /stripes/ not the number of /mirrors/. A result higher than 1 would be returned from lv_mirror_count, the MIRRORED flag would not be cleared, and the LV would fail to be up-converted properly in lvconvert_mirrors_aux because of it. --- WHATS_NEW | 1 + lib/metadata/mirror.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 95f79f4cb..15d239f5a 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.89 - ================================== + Fix lv_mirror_count to handle mirrored stripes properly. Fix failure to down-convert a mirror to linear due to udev "dev open" conflict Fix mirrored log creation when PE size is small - force log_size >= region_size Fix improper RAID 64-bit status flag reset when and'ing against 32-bit flag. diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c index e07597f9d..a4f906b77 100644 --- a/lib/metadata/mirror.c +++ b/lib/metadata/mirror.c @@ -114,16 +114,18 @@ uint32_t lv_mirror_count(const struct logical_volume *lv) return 1; seg = first_seg(lv); - mirrors = seg->area_count; + mirrors = 0; for (s = 0; s < seg->area_count; s++) { if (seg_type(seg, s) != AREA_LV) continue; if (is_temporary_mirror_layer(seg_lv(seg, s))) mirrors += lv_mirror_count(seg_lv(seg, s)) - 1; + else + mirrors++; } - return mirrors; + return mirrors ? mirrors : 1; } struct lv_segment *find_mirror_seg(struct lv_segment *seg) -- 2.43.5