summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlasdair G Kergon <agk@redhat.com>2016-05-23 22:55:13 +0100
committerAlasdair G Kergon <agk@redhat.com>2016-05-23 22:55:13 +0100
commitb896f7de1e6773ce6c17bf29a9123276695f4b60 (patch)
tree81416375ce783c38667cc210f83470848b2e83f5
parent757f7d55082844a17372e4e83c6a95884c2550a8 (diff)
downloadlvm2-b896f7de1e6773ce6c17bf29a9123276695f4b60.tar.gz
raid0: Standardise meta_areas checks before access.
-rw-r--r--lib/activate/dev_manager.c4
-rw-r--r--lib/metadata/lv.c4
-rw-r--r--lib/metadata/lv_manip.c8
-rw-r--r--lib/metadata/merge.c2
-rw-r--r--lib/metadata/raid_manip.c6
-rw-r--r--lib/metadata/segtype.h2
-rw-r--r--lib/raid/raid.c6
-rw-r--r--tools/lvchange.c2
-rw-r--r--tools/vgsplit.c6
9 files changed, 21 insertions, 19 deletions
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 711074d64..32295fb91 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -2207,7 +2207,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
(!dm->track_pending_delete || !lv_is_cache(lv)) &&
!_add_lv_to_dtree(dm, dtree, seg_lv(seg, s), 0))
return_0;
- if (seg_is_raid(seg) && seg->meta_areas && seg_metalv(seg, s) &&
+ if (seg_is_raid_with_meta(seg) && seg->meta_areas && seg_metalv(seg, s) &&
!_add_lv_to_dtree(dm, dtree, seg_metalv(seg, s), 0))
return_0;
}
@@ -2713,7 +2713,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
!_add_new_lv_to_dtree(dm, dtree, seg_lv(seg, s),
laopts, NULL))
return_0;
- if (seg_is_raid(seg) && seg->meta_areas && seg_metalv(seg, s) &&
+ if (seg_is_raid_with_meta(seg) && seg->meta_areas && seg_metalv(seg, s) &&
!_add_new_lv_to_dtree(dm, dtree, seg_metalv(seg, s),
laopts, NULL))
return_0;
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index cb30e2d59..0a531cfd8 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -53,7 +53,7 @@ static struct dm_list *_format_pvsegs(struct dm_pool *mem, const struct lv_segme
goto bad;
}
- if (metadata_areas_only && (!seg_is_raid(seg) || lv_is_raid_metadata(seg->lv) || lv_is_raid_image(seg->lv)))
+ if (metadata_areas_only && (!seg_is_raid_with_meta(seg) || !seg->meta_areas || lv_is_raid_metadata(seg->lv) || lv_is_raid_image(seg->lv)))
goto out;
for (s = 0; s < seg->area_count; s++) {
@@ -1012,7 +1012,7 @@ int lv_raid_healthy(const struct logical_volume *lv)
/* Find out which sub-LV this is. */
for (s = 0; s < raid_seg->area_count; s++)
if ((lv_is_raid_image(lv) && (seg_lv(raid_seg, s) == lv)) ||
- (lv_is_raid_metadata(lv) && (seg_metalv(raid_seg,s) == lv)))
+ (lv_is_raid_metadata(lv) && (seg_metalv(raid_seg, s) == lv)))
break;
if (s == raid_seg->area_count) {
log_error(INTERNAL_ERROR
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 82faf4296..2e9a7a3c4 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1019,7 +1019,7 @@ static int _release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t
}
/* Remove metadata area if image has been removed */
- if (area_reduction == seg->area_len) {
+ if (seg->meta_areas && seg_metalv(seg, s) && (area_reduction == seg->area_len)) {
if (!lv_reduce(seg_metalv(seg, s),
seg_metalv(seg, s)->le_count)) {
log_error("Failed to remove RAID meta-device %s",
@@ -3826,7 +3826,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
}
/* Extend metadata LVs only on initial creation */
- if (seg_is_raid(seg) && !seg_is_raid0(seg) && !lv->le_count) {
+ if (seg_is_raid_with_meta(seg) && !lv->le_count) {
if (!seg->meta_areas) {
log_error("No meta_areas for RAID type");
return 0;
@@ -4190,12 +4190,12 @@ static int _for_each_sub_lv(struct logical_volume *lv, int skip_pools,
return_0;
}
- if (!seg_is_raid(seg))
+ if (!seg_is_raid_with_meta(seg))
continue;
/* RAID has meta_areas */
for (s = 0; s < seg->area_count; s++) {
- if (seg_metatype(seg, s) != AREA_LV)
+ if ((seg_metatype(seg, s) != AREA_LV) || !seg_metalv(seg, s))
continue;
if (!fn(seg_metalv(seg, s), data))
return_0;
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index 4f730e07e..62fc70a24 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -441,7 +441,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
continue;
if (lv == seg_lv(seg, s))
seg_found++;
- if (seg_is_raid(seg) && (lv == seg_metalv(seg, s)))
+ if (seg_is_raid_with_meta(seg) && (lv == seg_metalv(seg, s)))
seg_found++;
}
if (seg_is_replicator_dev(seg)) {
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 887b27fd7..739e1449d 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -1871,8 +1871,8 @@ int lv_raid_remove_missing(struct logical_volume *lv)
*/
for (s = 0; s < seg->area_count; s++) {
- if (!lv_is_partial(seg_lv(seg, s)) &&
- !lv_is_partial(seg_metalv(seg, s)))
+ if (!lv_is_partial(seg_lv(seg, s)) &&
+ (!seg->meta_areas || !seg_metalv(seg, s) || !lv_is_partial(seg_metalv(seg, s))))
continue;
log_debug("Replacing %s and %s segments with error target",
@@ -1882,7 +1882,7 @@ int lv_raid_remove_missing(struct logical_volume *lv)
display_lvname(seg_lv(seg, s)));
return 0;
}
- if (!replace_lv_with_error_segment(seg_metalv(seg, s))) {
+ if (seg->meta_areas && !replace_lv_with_error_segment(seg_metalv(seg, s))) {
log_error("Failed to replace %s's extents with error target.",
display_lvname(seg_metalv(seg, s)));
return 0;
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
index 3fc42666c..f3b1510c4 100644
--- a/lib/metadata/segtype.h
+++ b/lib/metadata/segtype.h
@@ -119,6 +119,7 @@ struct dev_manager;
#define segtype_is_raid6_nr(segtype) ((segtype)->flags & SEG_RAID6_NR ? 1 : 0)
#define segtype_is_raid6_zr(segtype) ((segtype)->flags & SEG_RAID6_ZR ? 1 : 0)
#define segtype_is_raid10(segtype) ((segtype)->flags & SEG_RAID10 ? 1 : 0)
+#define segtype_is_raid_with_meta(segtype) (segtype_is_raid(segtype) && !segtype_is_raid0(segtype))
#define segtype_is_snapshot(segtype) ((segtype)->flags & SEG_SNAPSHOT ? 1 : 0)
#define segtype_is_striped(segtype) ((segtype)->flags & SEG_AREAS_STRIPED ? 1 : 0)
#define segtype_is_thin(segtype) ((segtype)->flags & (SEG_THIN_POOL|SEG_THIN_VOLUME) ? 1 : 0)
@@ -148,6 +149,7 @@ struct dev_manager;
#define seg_is_raid6_nr(seg) segtype_is_raid6_nr((seg)->segtype)
#define seg_is_raid6_nc(seg) segtype_is_raid6_nc((seg)->segtype)
#define seg_is_raid10(seg) segtype_is_raid10((seg)->segtype)
+#define seg_is_raid_with_meta(seg) segtype_is_raid_with_meta((seg)->segtype)
#define seg_is_replicator(seg) ((seg)->segtype->flags & SEG_REPLICATOR ? 1 : 0)
#define seg_is_replicator_dev(seg) ((seg)->segtype->flags & SEG_REPLICATOR_DEV ? 1 : 0)
#define seg_is_snapshot(seg) segtype_is_snapshot((seg)->segtype)
diff --git a/lib/raid/raid.c b/lib/raid/raid.c
index 4987f9175..e299e1780 100644
--- a/lib/raid/raid.c
+++ b/lib/raid/raid.c
@@ -33,10 +33,10 @@ static void _raid_display(const struct lv_segment *seg)
display_stripe(seg, s, " ");
}
- if (seg->meta_areas) {
+ if (seg->meta_areas)
for (s = 0; s < seg->area_count; ++s)
- log_print(" Raid Metadata LV%2d\t%s", s, seg_metalv(seg, s)->name);
- }
+ if (seg_metalv(seg, s))
+ log_print(" Raid Metadata LV%2d\t%s", s, seg_metalv(seg, s)->name);
log_print(" ");
}
diff --git a/tools/lvchange.c b/tools/lvchange.c
index c37a59750..1ce19c582 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -243,7 +243,7 @@ static int detach_metadata_devices(struct lv_segment *seg, struct dm_list *list)
if (!(lvl = dm_pool_alloc(seg->lv->vg->vgmem, sizeof(*lvl) * num_meta_lvs)))
return_0;
- if (seg_is_raid(seg)) {
+ if (seg_is_raid_with_meta(seg)) {
for (s = 0; s < seg->area_count; s++) {
if (!seg_metalv(seg, s))
return_0; /* Trap this future possibility */
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index 8335570bc..e7c6e191b 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -253,11 +253,11 @@ static int _move_raid(struct volume_group *vg_from,
for (s = 0; s < seg->area_count; s++) {
if (_lv_is_in_vg(vg_to, seg_lv(seg, s)))
seg_in++;
- if (_lv_is_in_vg(vg_to, seg_metalv(seg, s)))
- seg_in++;
+ if (seg->meta_areas && seg_metalv(seg, s) && _lv_is_in_vg(vg_to, seg_metalv(seg, s)))
+ seg_in++; /* FIXME Inadequate - must count separately */
}
- if (seg_in && seg_in != (seg->area_count * 2)) {
+ if (seg_in && seg_in != (seg->area_count * (seg->meta_areas ? 2 : 1))) {
log_error("Can't split RAID %s between "
"two Volume Groups", lv->name);
return 0;