summaryrefslogtreecommitdiff
path: root/lib/metadata/merge.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/metadata/merge.c')
-rw-r--r--lib/metadata/merge.c71
1 files changed, 49 insertions, 22 deletions
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index bb533e9ee..40c7c4aa0 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -20,15 +20,6 @@
#include "str_list.h"
#include "segtype.h"
-/* HM FIXME: REMOVEME: devel output */
-#ifdef USE_PFL
-#define PFL() printf("%s %u\n", __func__, __LINE__);
-#define PFLA(format, arg...) printf("%s %u " format "\n", __func__, __LINE__, arg);
-#else
-#define PFL()
-#define PFLA(format, arg...)
-#endif
-
/*
* Attempt to merge two adjacent segments.
* Currently only supports striped segments on AREA_PV.
@@ -102,6 +93,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
lv->name);
inc_error_count;
} else if (!seg_is_thin_volume(first_seg(lv))) {
+PFLA("segtype=%s", lvseg_name(first_seg(lv)));
log_error("LV %s is thin volume without first thin volume segment.",
lv->name);
inc_error_count;
@@ -139,6 +131,8 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
}
dm_list_iterate_items(seg, &lv->segments) {
+ uint32_t data_copies, data_rimage_count;
+
seg_count++;
if (seg->le != le) {
log_error("LV %s invalid: segment %u should begin at "
@@ -147,13 +141,27 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
inc_error_count;
}
- area_multiplier = seg_is_striped(seg) ? seg->area_count - seg->segtype->parity_devs : 1;
+ area_multiplier = (seg_is_striped_raid(seg) || seg_is_striped(seg)) ? seg->area_count - seg->segtype->parity_devs : 1;
+ data_rimage_count = seg->area_count - seg->segtype->parity_devs;
+
+PFLA("lv=%s segtype=%s seg->len=%u seg->area_len=%u seg->area_count=%u data_rimage_count=%u parity_devs=%u area_multiplier=%u seg->data_copies=%u rimageextents=%u seg->reshape_len=%u", lv->name, seg->segtype->name, seg->len, seg->area_len, seg->area_count, data_rimage_count, seg->segtype->parity_devs, area_multiplier, seg->data_copies, raid_rimage_extents(seg->segtype, seg->len - data_rimage_count * seg->reshape_len, data_rimage_count, seg->data_copies), seg->reshape_len);
+#if 1
+ data_copies = seg_is_any_raid10(seg) ? seg->data_copies : 1;
+ if (raid_rimage_extents(seg->segtype, seg->len - data_rimage_count * seg->reshape_len,
+ data_rimage_count, seg->data_copies) != seg->area_len - data_copies * seg->reshape_len) {
+#else
+ if (seg->area_len * area_multiplier != seg->len) {
+#endif
+ log_error("LV %s: segment %u with len=%u "
+ " has inconsistent area_len %u",
+ lv->name, seg_count, seg->len, seg->area_len);
+ inc_error_count;
+ }
-PFLA("segtype=%s seg->area_len=%u seg->area_count=%u parity_devs=%u area_multiplier=%u seg->len=%u", seg->segtype->name, seg->area_len, seg->area_count, seg->segtype->parity_devs, area_multiplier, seg->len);
- if (seg->area_len * area_multiplier != seg->len) { // - seg->reshape_len) {
- log_error("LV %s: segment %u has inconsistent "
- "area_len %u",
- lv->name, seg_count, seg->area_len);
+ if (lv_is_error_when_full(lv) &&
+ !seg_can_error_when_full(seg)) {
+ log_error("LV %s: segment %u (%s) does not support flag "
+ "ERROR_WHEN_FULL.", lv->name, seg_count, seg->segtype->name);
inc_error_count;
}
@@ -211,6 +219,26 @@ PFLA("segtype=%s seg->area_len=%u seg->area_count=%u parity_devs=%u area_multipl
}
}
+ if (seg_is_cache_pool(seg) &&
+ !dm_list_empty(&seg->lv->segs_using_this_lv)) {
+ switch (seg->feature_flags &
+ (DM_CACHE_FEATURE_PASSTHROUGH |
+ DM_CACHE_FEATURE_WRITETHROUGH |
+ DM_CACHE_FEATURE_WRITEBACK)) {
+ case DM_CACHE_FEATURE_PASSTHROUGH:
+ case DM_CACHE_FEATURE_WRITETHROUGH:
+ case DM_CACHE_FEATURE_WRITEBACK:
+ break;
+ default:
+ log_error("LV %s has invalid cache's feature flag.",
+ lv->name);
+ inc_error_count;
+ }
+ if (!seg->policy_name) {
+ log_error("LV %s is missing cache policy name.", lv->name);
+ inc_error_count;
+ }
+ }
if (seg_is_pool(seg)) {
if (seg->area_count != 1 ||
seg_type(seg, 0) != AREA_LV) {
@@ -234,8 +262,7 @@ PFLA("segtype=%s seg->area_len=%u seg->area_count=%u parity_devs=%u area_multipl
inc_error_count;
}
- if (seg_is_pool(seg) &&
- !validate_pool_chunk_size(lv->vg->cmd, seg->segtype, seg->chunk_size)) {
+ if (!validate_pool_chunk_size(lv->vg->cmd, seg->segtype, seg->chunk_size)) {
log_error("LV %s: %s segment %u has invalid chunk size %u.",
lv->name, seg->segtype->name, seg_count, seg->chunk_size);
inc_error_count;
@@ -413,7 +440,6 @@ PFLA("segtype=%s seg->area_len=%u seg->area_count=%u parity_devs=%u area_multipl
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_LV)
continue;
-PFLA("lv=%s s=%u seg->status=%lX seg_lv(seg, %u)=%s", lv->name, s, seg->status, s, seg_lv(seg, s)->name);
/* HM FIXME: TESTME */
if (seg_is_raid(seg) && seg->meta_areas && lv == seg_metalv(seg, s))
{
@@ -486,7 +512,7 @@ PFLA("lv=%s s=%u seg->status=%lX seg_lv(seg, %u)=%s", lv->name, s, seg->status,
inc_error_count;
}
}
-PFL();
+PFLA("error_count=%u", error_count);
if (le != lv->le_count) {
log_error("LV %s: inconsistent LE count %u != %u",
@@ -521,7 +547,7 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
seg->lv, seg->le, seg->len, seg->reshape_len,
seg->status, seg->stripe_size,
seg->log_lv,
- seg->area_count, seg->area_len,
+ seg->area_count, seg->area_len, seg->data_copies,
seg->chunk_size, seg->region_size,
seg->extents_copied, seg->pvmove_source_seg))) {
log_error("Couldn't allocate cloned LV segment.");
@@ -533,9 +559,10 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
return 0;
}
- /* In case of a striped segment, the offset has to be / stripes */
+ /* In case of a striped/raid10_far segment, the offset has to be / stripes */
area_offset = offset;
- if (seg_is_striped(seg))
+ if (seg_is_striped(seg) ||
+ seg_is_raid10_far(seg))
area_offset /= seg->area_count;
split_seg->area_len -= area_offset;