summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2015-11-05 17:01:52 +0100
committerHeinz Mauelshagen <heinzm@redhat.com>2015-11-05 17:01:52 +0100
commit1dd4629cacbab9bf3ec66e1f17c117b3c0eb170c (patch)
tree292ae50eb0559ea7e0818af03b4b24779cfb69d8
parent7907c3ff6e0aa3b4dd823bef49d1cbe120386bcd (diff)
downloadlvm2-1dd4629cacbab9bf3ec66e1f17c117b3c0eb170c.tar.gz
raid_manip:
more RETURN_IF_*() added introduce LV_RESHAPE_REMOVE flag lv_manip: reshape_len corrections report.c: enhanced stripes and data stripes to pay attention to LV_RESHAPE_REMOVE flag
-rw-r--r--lib/format_text/flags.c1
-rw-r--r--lib/metadata/lv.c2
-rw-r--r--lib/metadata/lv_manip.c56
-rw-r--r--lib/metadata/merge.c16
-rw-r--r--lib/metadata/metadata-exported.h5
-rw-r--r--lib/metadata/raid_manip.c803
-rw-r--r--lib/report/columns.h3
-rw-r--r--lib/report/report.c31
8 files changed, 456 insertions, 461 deletions
diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c
index 03ca0a3ab..5baeaa143 100644
--- a/lib/format_text/flags.c
+++ b/lib/format_text/flags.c
@@ -63,6 +63,7 @@ static const struct flag _lv_flags[] = {
{LV_REBUILD, "REBUILD", STATUS_FLAG},
{LV_RESHAPE_DELTA_DISKS_PLUS, "RESHAPE_DELTA_DISKS_PLUS", STATUS_FLAG},
{LV_RESHAPE_DELTA_DISKS_MINUS, "RESHAPE_DELTA_DISKS_MINUS", STATUS_FLAG},
+ {LV_RESHAPE_REMOVED, "RESHAPE_REMOVED", STATUS_FLAG},
{LV_WRITEMOSTLY, "WRITEMOSTLY", STATUS_FLAG},
{LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
{LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG},
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 45ef2459b..c1b974347 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -798,6 +798,8 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
repstr[8] = 'm'; /* RAID has 'm'ismatches */
} else if (lv->status & LV_WRITEMOSTLY)
repstr[8] = 'w'; /* sub-LV has 'w'ritemostly */
+ else if (lv->status & LV_RESHAPE_REMOVED)
+ repstr[8] = 'R'; /* sub-LV got 'R'emoved from raid set by reshaping */
} else if (lv_is_thin_pool(lv) &&
(lvdm->seg_status.type != SEG_STATUS_NONE)) {
if (lvdm->seg_status.type == SEG_STATUS_UNKNOWN)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 14ad770fe..33b9e3804 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1295,7 +1295,7 @@ static uint32_t _seg_area_len(struct lv_segment *seg, uint32_t extents)
PFLA("lv=%s extents=%u", display_lvname(seg->lv), extents);
PFLA("segtype=%s stripes=%u data_copies=%u", lvseg_name(seg), stripes, seg->data_copies);
- r = raid_rimage_extents(seg->segtype, extents - seg->reshape_len * seg->area_count,
+ r = raid_rimage_extents(seg->segtype, extents - seg->reshape_len * stripes,
stripes, seg->data_copies ?: 1);
PFLA("area_len=%u", r);
@@ -1878,7 +1878,6 @@ PFLA("ah->area_multiple=%u area_count=%u new_extents=%u total_extents=%u", ah->a
#endif
PFLA("total_extents=%u stripes=%u mirrors=%u", total_extents, stripes, mirrors);
-
if (metadata_area_count) {
uint32_t cur_rimage_extents, new_rimage_extents;
@@ -1934,7 +1933,8 @@ PFLA("ah->log_area_count=%u ah->log_len=%u existing_extents=%u total_extents=%u"
log_debug("Adjusted allocation request to %" PRIu32 " logical extents. Existing size %" PRIu32 ". New size %" PRIu32 ".",
total_extents, existing_extents, total_extents + existing_extents);
- if (extend && (mirrors || stripes))
+ // if (extend && (mirrors || stripes))
+ if (mirrors || stripes)
total_extents += existing_extents;
#if 1
PFLA("total_extents=%u", total_extents);
@@ -3423,6 +3423,7 @@ static int _allocate(struct alloc_handle *ah,
extents_still_needed = ah->new_extents - alloc_state.allocated;
rimage_extents = raid_rimage_extents(ah->segtype, ah->new_extents, ah->area_count, 1);
goto skip;
+
PFLA("extents_still_needed=%u rimage_extents=%u", ah->new_extents - alloc_state.allocated, rimage_extents);
if (extents_still_needed > rimage_extents &&
(extents_still_needed % rimage_extents)) {
@@ -3597,15 +3598,10 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
alloc_policy_t alloc, int approx_alloc,
struct dm_list *parallel_areas)
{
- int extend = 0;
+ int extend = (lv && lv->le_count) ? 1 : 0;
struct lv_segment *seg = lv ? first_seg(lv) : NULL;
struct alloc_handle *ah;
- if (seg &&
- mirrors == seg->data_copies &&
- stripes == seg->area_count - seg->segtype->parity_devs)
- extend = 1;
-
PFLA("segtype=%s stripes=%u mirrors=%u, log_count=%u, region_size=%u extents=%u",
segtype->name, stripes, mirrors, log_count, region_size, extents);
@@ -4295,7 +4291,7 @@ PFLA("extending %s in %s, stripes=%u", display_lvname(sub_lv), lv->name, stripes
return 0;
}
-PFLA("first_seg(seg_lv(seg, s))->len=%u", first_seg(seg_lv(seg, s))->len);
+PFLA("last_seg(seg_lv(seg, s))->len=%u last_seg(seg_lv(seg, s))->area_len=%u", last_seg(seg_lv(seg, s))->len, last_seg(seg_lv(seg, s))->area_len);
/* Add any pre-allocated and pre-wiped metadata LVs */
if (!dm_list_empty(meta_lvs)) {
@@ -4315,9 +4311,9 @@ PFLA("first_seg(seg_lv(seg, s))->len=%u", first_seg(seg_lv(seg, s))->len);
seg->len += extents;
seg->area_len = _seg_area_len(seg, seg->len) + seg->reshape_len;
#endif
-PFLA("segtye=%s lv->le_count=%u", lvseg_name(seg), lv->le_count);
+PFLA("segtye=%s lv->le_count=%u seg->len=%u seg->area_len=%u", lvseg_name(seg), lv->le_count, seg->len, seg->area_len);
lv->le_count += extents;
- lv->size += (uint64_t) extents * lv->vg->extent_size;
+ lv->size = (uint64_t) lv->le_count * lv->vg->extent_size;
PFLA("lv->le_count=%u", lv->le_count);
/*
@@ -4353,7 +4349,7 @@ int lv_extend(struct logical_volume *lv,
{
int r = 1;
int log_count = 0;
- uint32_t s;
+ uint32_t area_count, s;
struct alloc_handle *ah;
uint32_t sub_lv_count;
uint32_t old_extents;
@@ -4389,22 +4385,21 @@ PFLA("recursive seg_lv(seg, %u)=%s extents=%u", s, display_lvname(lv1), extents)
lv->size = (uint64_t) lv->le_count * lv->vg->extent_size;
return 1;
}
-
#endif
/* Caller should ensure... */
- if (seg_is_raid(seg)) {
+ if (seg_is_striped(seg) ||
+ seg_is_striped_raid(seg)) {
+ area_count = seg->area_count;
+ stripes = area_count - seg->segtype->parity_devs;
mirrors = seg->data_copies;
- stripes = seg_is_striped_raid(seg) ? seg->area_count - seg->segtype->parity_devs : 1;
-
- } else if (seg_is_mirror(seg)) {
- mirrors = seg->area_count;
- stripes = 1;
-
+
} else {
- mirrors = 1;
- stripes = seg->area_count;
+ stripes = 1;
+ area_count = mirrors = seg->data_copies;
}
- }
+
+ } else
+ area_count = max(stripes + segtype->parity_devs, mirrors);
PFLA("mirrors=%u stripes=%u", mirrors, stripes);
if (segtype_is_virtual(segtype))
@@ -4449,11 +4444,22 @@ PFLA("extents=%u mirrors=%u stripes=%u log_count=%u", extents, mirrors, stripes,
return 0;
}
- if (!(ah = allocate_extents(lv->vg, lv, segtype, stripes, mirrors,
+ if (!(ah = allocate_extents(lv->vg, lv, segtype, (lv->le_count && mirrors == 1) ? area_count : stripes, mirrors,
log_count, region_size, extents,
allocatable_pvs, alloc, approx_alloc, NULL)))
return_0;
+{
+struct alloced_area *aa;
+
+for (s = 0; s < ah->area_count + ah->log_area_count; s++) {
+dm_list_iterate_items(aa, ah->alloced_areas + s)
+{
+PFLA("%u aa->len=%u", s >= ah->log_area_count ? s - ah->log_area_count : s, aa->len);
+}
+}
+}
+
if (segtype_is_pool(segtype)) {
if (!(r = create_pool(lv, segtype, ah, stripes, stripe_size)))
stack;
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index 57841fbb9..10d063c8f 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -70,6 +70,20 @@ int lv_merge_segments(struct logical_volume *lv)
if (error_count++ > ERROR_MAX) \
goto out
+/* Return number of data rimages for @seg paying attention to delta disks (reshaping) */
+static uint32_t _data_rimage_count(struct lv_segment *seg)
+{
+ uint32_t r = seg->area_count - seg->segtype->parity_devs, s;
+
+#if 0
+ for (s = 0; s < seg->area_count; s++)
+ if (seg_type(seg, s) == AREA_LV &&
+ (seg_lv(seg, s)->status & LV_RESHAPE_DELTA_DISKS_MINUS))
+ r--;
+#endif
+
+ return r;
+}
/*
* Verify that an LV's segments are consecutive, complete and don't overlap.
*/
@@ -141,8 +155,8 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
}
area_multiplier = (seg_is_striped_raid(seg) || seg_is_striped(seg)) ? seg->area_count - seg->segtype->parity_devs : 1;
+ data_rimage_count = _data_rimage_count(seg);
- 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
if (raid_rimage_extents(seg->segtype, seg->len - data_rimage_count * seg->reshape_len, data_rimage_count,
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 15ab08e39..d90ebb1d4 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -135,9 +135,10 @@
FIXME: Remove this flag once we have indexed
vg->removed_lvs for quick lookup.
*/
-#define LV_ERROR_WHEN_FULL UINT64_C(0x0080000000000000) /* LV - error when full */
+#define LV_ERROR_WHEN_FULL UINT64_C(0x0080000000000000) /* LV - error when full */
#define LOCKD_SANLOCK_LV UINT64_C(0x0100000000000000) /* LV - Internal use only */
-/* Next unused flag: UINT64_C(0x0200000000000000) */
+#define LV_RESHAPE_REMOVED UINT64_C(0x0200000000000000) /* LV got removed from raid set by shrinking reshape */
+/* Next unused flag: UINT64_C(0x0400000000000000) */
/* Format features flags */
#define FMT_SEGMENTS 0x00000001U /* Arbitrary segment params? */
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 7a61c4015..9b7719066 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -40,18 +40,23 @@
#define RETURN_IF_ZERO(arg, msg) \
RETURN_IF_NONZERO(!(arg), (msg))
-/* Macro to check @lv, it's first segment and the new segment type exist */
-#define RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, seg, segtype) \
+/* Macro to check @lv and it's first segment exist */
+#define RETURN_IF_LV_SEG_ZERO(lv, seg) \
RETURN_IF_ZERO((lv), "lv argument"); \
- RETURN_IF_ZERO((seg), "lv segment argument"); \
+ RETURN_IF_ZERO((seg), "lv segment argument");
+
+/* Macro to check @lv, it's first segment and the new segment type exist */
+#define RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, seg, segtype) \
+ RETURN_IF_LV_SEG_ZERO((lv), (seg)); \
RETURN_IF_ZERO((segtype), "lv new segment type argument");
/* Ensure minimum region size on @lv */
static int _ensure_min_region_size(struct logical_volume *lv)
{
- RETURN_IF_ZERO(lv, "lv argument");
+ struct lv_segment *seg;
+
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
- struct lv_segment *seg = first_seg(lv);
/* MD's bitmap is limited to tracking 2^21 regions */
uint32_t min_region_size = lv->size / (1 << 21);
uint32_t region_size = seg->region_size;
@@ -83,9 +88,7 @@ static int _check_and_init_region_size(struct logical_volume *lv)
{
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
seg->region_size = seg->region_size ?: get_default_region_size(lv->vg->cmd);
@@ -96,9 +99,8 @@ static int _check_and_init_region_size(struct logical_volume *lv)
static uint32_t _data_rimages_count(const struct lv_segment *seg, const uint32_t total_rimages)
{
RETURN_IF_ZERO(seg, "lv raid segment");
-
- if (total_rimages < seg->segtype->parity_devs)
- RETURN_IF_ZERO(0, "too little total rimages count");
+ RETURN_IF_NONZERO(total_rimages < seg->segtype->parity_devs,
+ "too little total rimages count");
return total_rimages - seg->segtype->parity_devs;
}
@@ -159,9 +161,7 @@ static int _lv_is_raid_with_tracking(const struct logical_volume *lv,
uint32_t s;
const struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
*tracking = NULL;
@@ -191,9 +191,9 @@ int lv_is_raid_with_tracking(const struct logical_volume *lv)
static int _lv_is_duplicating(const struct logical_volume *lv)
{
uint32_t s;
- struct lv_segment *seg = first_seg(lv);
+ struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
/* Needs to be raid1 with >= 2 legs and the legs must have the proper names suffix */
if (!seg ||
@@ -217,7 +217,9 @@ static int _lv_is_duplicating(const struct logical_volume *lv)
uint32_t lv_raid_image_count(const struct logical_volume *lv)
{
- struct lv_segment *seg = first_seg(lv);
+ struct lv_segment *seg;
+
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
return seg_is_raid(seg) ? seg->area_count : 1;
}
@@ -228,7 +230,10 @@ uint32_t raid_rimage_extents(const struct segment_type *segtype,
{
uint64_t r;
- if (segtype_is_raid1(segtype))
+ RETURN_IF_ZERO(segtype, "segtype argument");
+
+ if (!extents ||
+ segtype_is_raid1(segtype))
return extents;
/* Caller should ensure... */
@@ -239,13 +244,10 @@ uint32_t raid_rimage_extents(const struct segment_type *segtype,
segtype_is_raid01(segtype))
return extents / stripes;
- /* Caller should ensure... */
- if (!data_copies)
- data_copies = 1;
-
r = extents;
if (segtype_is_any_raid10(segtype))
- r *= data_copies;
+ /* Caller should ensure... */
+ r *= data_copies ?: 1;
r = dm_div_up(r, stripes);
@@ -256,6 +258,9 @@ uint32_t raid_rimage_extents(const struct segment_type *segtype,
uint32_t raid_total_extents(const struct segment_type *segtype,
uint32_t extents, uint32_t stripes, uint32_t data_copies)
{
+ RETURN_IF_ZERO(segtype, "segtype argument");
+ RETURN_IF_ZERO(extents, "extents > 0");
+
return raid_rimage_extents(segtype, extents, stripes, data_copies) * stripes;
}
@@ -285,9 +290,7 @@ static int _lv_set_image_lvs_start_les(struct logical_volume *lv)
uint32_t le, s;
struct lv_segment *raid_seg, *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- raid_seg = first_seg(lv);
- RETURN_IF_ZERO(raid_seg, "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (raid_seg = first_seg(lv)));
RETURN_IF_ZERO(raid_seg->area_count, "raid segment areas");
for (s = 0; s < raid_seg->area_count; s++) {
@@ -398,8 +401,7 @@ static int _dev_in_sync(struct logical_volume *lv, const unsigned idx)
char *raid_health;
RETURN_IF_ZERO(lv, "lv argument");
- if (idx >= first_seg(lv)->area_count)
- RETURN_IF_ZERO(0, "bogus index");
+ RETURN_IF_NONZERO(idx >= first_seg(lv)->area_count, "bogus index");
if (!_get_dev_health(lv, &kernel_devs, &devs_health, &devs_in_sync, &raid_health) ||
idx >= kernel_devs)
@@ -435,10 +437,7 @@ static int _raid_in_sync(struct logical_volume *lv)
dm_percent_t sync_percent;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
-
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
if (seg_is_striped(seg) || seg_is_any_raid0(seg))
return 1;
@@ -533,14 +532,15 @@ static int _yes_no_conversion(const struct logical_volume *lv,
int segtype_change, stripes_change, stripe_size_change;
unsigned cur_redundancy, new_redundancy;
struct lv_segment *seg;
- struct segment_type *new_segtype_tmp = (struct segment_type *) new_segtype;
+ struct segment_type *new_segtype_tmp;
const struct segment_type *segtype;
struct lvinfo info = { 0 };
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(new_data_copies, "new data copies");
+ RETURN_IF_ZERO(new_segtype, "segment type argument");
+
+ new_segtype_tmp = (struct segment_type *) new_segtype; /* Drop const */
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) && driver_version(NULL, 0)) {
log_error("Unable to retrieve logical volume information: aborting");
@@ -719,9 +719,9 @@ static int _convert_raid_to_linear(struct logical_volume *lv,
struct dm_list *removal_lvs)
{
struct logical_volume *lv_tmp;
- struct lv_segment *seg = first_seg(lv);
+ struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(removal_lvs, "removal lv list argument");
if (!seg_is_any_raid0(seg) &&
@@ -1063,8 +1063,7 @@ static int _shift_image_name(struct logical_volume *lv, unsigned s, unsigned mis
{
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
if (strstr(lv->name, "_dup_") &&
(seg_is_raid(seg) || seg_is_mirror(seg))) {
@@ -1215,11 +1214,11 @@ static int _realloc_seg_areas(struct logical_volume *lv,
uint32_t areas, uint64_t type)
{
uint32_t s;
- struct lv_segment *seg = first_seg(lv);
+ struct lv_segment *seg;
struct lv_segment_area **seg_areas;
struct lv_segment_area *new_areas;
- RETURN_IF_ZERO(lv, "lv argument");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(areas, "areas count");
switch (type) {
@@ -1281,9 +1280,8 @@ static int _extract_image_component_error_seg(struct lv_segment *seg,
RETURN_IF_ZERO(seg, "lv segment argument");
RETURN_IF_ZERO(extracted_lv, "extracted lvs argument");
- if (set_error_seg < 0 || set_error_seg > 1) {
- RETURN_IF_ZERO(0, "set error segment argument");
- }
+ RETURN_IF_NONZERO(set_error_seg < 0 || set_error_seg > 1,
+ "set error segment argument");
switch (type) {
case RAID_META:
@@ -1543,6 +1541,7 @@ uint32_t raid_rmeta_extents_delta(struct cmd_context *cmd,
{
uint32_t rmeta_extents_cur = _raid_rmeta_extents(cmd, rimage_extents_cur, region_size, extent_size);
uint32_t rmeta_extents_new = _raid_rmeta_extents(cmd, rimage_extents_new, region_size, extent_size);
+
PFLA("rimage_extents_cur=%u rmeta_extents_cur=%u rimage_extents_new=%u rmeta_extents_new=%u region_size=%u extent_size=%u", rimage_extents_cur, rmeta_extents_cur, rimage_extents_new, rmeta_extents_new, region_size, extent_size);
/* Need minimum size on LV creation */
if (!rimage_extents_cur)
@@ -1563,7 +1562,7 @@ PFLA("rimage_extents_cur=%u rmeta_extents_cur=%u rimage_extents_new=%u rmeta_ext
/*
* _alloc_rmeta_for_lv
- * @lv
+ * @data_lv
*
* Allocate RAID metadata device for the given LV (which is or will
* be the associated RAID data device). The new metadata device must
@@ -1576,10 +1575,16 @@ static int __alloc_rmeta_for_lv(struct logical_volume *data_lv,
int r = 1;
char *p;
struct alloc_handle *ah;
- struct lv_segment *seg = first_seg(data_lv);
+ struct lv_segment *seg;
struct dm_list pvs;
- if (!allocate_pvs) {
+ RETURN_IF_LV_SEG_ZERO(data_lv, (seg = first_seg(data_lv)));
+ RETURN_IF_ZERO(meta_lv, "mate lv argument");
+
+ if (allocate_pvs) {
+ RETURN_IF_NONZERO(dm_list_empty(allocate_pvs), "allocate pvs listed");
+
+ } else {
allocate_pvs = &pvs;
dm_list_init(allocate_pvs);
if (!get_pv_list_for_lv(data_lv->vg->cmd->mem,
@@ -1622,6 +1627,8 @@ PFLA("meta_lv=%s le_count=%u", display_lvname(*meta_lv), (*meta_lv)->le_count);
static int _alloc_rmeta_for_lv(struct logical_volume *data_lv,
struct logical_volume **meta_lv)
{
+ RETURN_IF_LV_SEG_ZERO(data_lv, first_seg(data_lv));
+
return __alloc_rmeta_for_lv(data_lv, meta_lv, NULL);
}
@@ -1638,6 +1645,12 @@ static int _alloc_rmeta_devs_for_rimage_devs(struct logical_volume *lv,
struct dm_list *l;
struct lv_list *lvl, *lvl_array;
+ RETURN_IF_ZERO(lv, "lv argument");
+ RETURN_IF_ZERO(new_data_lvs, "new data lvs argument");
+ RETURN_IF_NONZERO(dm_list_empty(new_data_lvs), "new data lvs listed");
+ RETURN_IF_ZERO(new_meta_lvs, "new meta lvs argument");
+ RETURN_IF_NONZERO(!dm_list_empty(new_meta_lvs), "new meta lvs may be listed");
+
dm_list_iterate(l, new_data_lvs)
raid_devs++;
@@ -1675,14 +1688,14 @@ static int _alloc_rmeta_devs_for_lv(struct logical_volume *lv, struct dm_list *m
uint32_t s;
struct lv_list *lvl_array;
struct dm_list data_lvs;
- struct lv_segment *seg = first_seg(lv);
+ struct lv_segment *seg;
- dm_list_init(&data_lvs);
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
+ RETURN_IF_ZERO(meta_lvs, "mate lvs list argument");
+ RETURN_IF_NONZERO(seg->meta_areas, "meta lvs may exist");
+ RETURN_IF_ZERO(seg->area_count, "segment areas");
- if (seg->meta_areas) {
- log_error(INTERNAL_ERROR "Metadata LVs exist in %s", display_lvname(lv));
- return 0;
- }
+ dm_list_init(&data_lvs);
if (!(seg->meta_areas = dm_pool_zalloc(lv->vg->vgmem,
seg->area_count * sizeof(*seg->meta_areas))))
@@ -1723,28 +1736,19 @@ static int _alloc_image_components(struct logical_volume *lv,
{
int r = 0;
uint32_t s, extents;
- struct lv_segment *seg = first_seg(lv);
- const struct segment_type *segtype;
+ struct lv_segment *seg;
struct alloc_handle *ah;
struct dm_list *parallel_areas;
struct lv_list *lvl_array;
- if (!meta_lvs && !data_lvs)
- return 0;
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
+ RETURN_IF_NONZERO(!meta_lvs && !data_lvs, "data and meta lvs list argument");
if (!(lvl_array = dm_pool_alloc(lv->vg->vgmem, 2 * count * sizeof(*lvl_array))))
return_0;
if (!_check_and_init_region_size(lv))
return 0;
-
- /* If this is an image addition to an existing raid set, use its type... */
- if (seg_is_raid(seg))
- segtype = seg->segtype;
-
- /* .. if not, set it to raid1 */
- else if (!(segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID1)))
- return_0;
PFL();
/*
* The number of extents is based on the RAID type. For RAID1,
@@ -1755,25 +1759,24 @@ PFL();
* is along with the number we want ('count').
*/
if (pvs) {
- uint32_t stripes, data_copies;
+ uint32_t data_copies;
+ const struct segment_type *segtype;
if (!(parallel_areas = build_parallel_areas_from_lv(lv, 0, 1)))
return_0;
/* Amount of extents for the rimage device(s) */
- if (seg_is_striped_raid(seg)) {
- stripes = count;
- data_copies = 1;
- } else {
- stripes = 1;
- data_copies = count;
- }
-
+ data_copies = count;
extents = seg->area_len;
-PFLA("stripes=%u extents=%u lv->le_count=%u seg->area_count=%u data_copies=%u", stripes, extents, lv->le_count, seg->area_count, data_copies);
+PFLA("count=%u extents=%u lv->le_count=%u seg->area_count=%u data_copies=%u", count, extents, lv->le_count, seg->area_count, data_copies);
+ /* Use raid1 segtype for allocation to get images of the same size as the given ones in @lv */
+ if (!(segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID1)))
+ return_0;
+
if (!(ah = allocate_extents(lv->vg, NULL, segtype,
- stripes, data_copies, count /* metadata_area_count */,
- seg->region_size, extents,
+ // data_copies, 1 /* stripes */, count /* metadata_area_count */,
+ 1 /* stripes */, data_copies, count /* metadata_area_count */,
+ 0 /* region_size */, extents,
pvs, lv->alloc, 0, parallel_areas)))
return_0;
@@ -1845,9 +1848,14 @@ static int _raid_extract_images(struct logical_volume *lv, uint32_t new_image_co
int inc;
unsigned s, extract;
struct lv_list *lvl_pairs;
- struct lv_segment *seg = first_seg(lv);
+ struct lv_segment *seg;
struct segment_type *error_segtype;
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
+ RETURN_IF_ZERO(target_pvs, "target pvs list argument");
+ RETURN_IF_ZERO(extracted_meta_lvs, "extracted meta lvs list argument");
+ RETURN_IF_ZERO(extracted_data_lvs, "extracted data lvs list argument");
+
extract = seg->area_count - new_image_count;
if ((s = dm_list_size(target_pvs)) < extract) {
@@ -1973,19 +1981,18 @@ PFL();
* LVs on the @removal_lvs list
*/
static int _lv_change_image_count(struct logical_volume *lv,
- const struct segment_type *new_segtype,
uint32_t new_image_count,
struct dm_list *allocate_pvs,
struct dm_list *removal_lvs)
{
- struct lv_segment *seg = first_seg(lv);
+ struct lv_segment *seg;
struct dm_list meta_lvs, data_lvs;
- uint32_t old_image_count = seg->area_count;
+ uint32_t old_image_count;
- RETURN_IF_ZERO(lv, "LV argument");
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(new_image_count, "new image count");
+ old_image_count = seg->area_count;
if (old_image_count == new_image_count) {
log_warn("%s already has image count of %d.",
display_lvname(lv), new_image_count);
@@ -2033,7 +2040,7 @@ static int _lv_change_image_count(struct logical_volume *lv,
}
} else {
- RETURN_IF_ZERO(removal_lvs, "removal lvs list");
+ RETURN_IF_ZERO(removal_lvs, "removal lvs list argument");
/*
* Extract all image and any metadata lvs past new_image_count
@@ -2069,9 +2076,7 @@ static int _relocate_reshape_space(struct logical_volume *lv, int to_end)
struct lv_segment *data_seg;
struct dm_list *where;
- RETURN_IF_ZERO(lv, "LV argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
if (!_reshape_len_per_dev(seg)) {
log_error(INTERNAL_ERROR "No reshape space to relocate");
@@ -2135,15 +2140,15 @@ static int _lv_set_reshape_len(struct logical_volume *lv, uint32_t reshape_len)
uint32_t s;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "LV argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(seg->area_count, "lv raid segment areas");
seg->reshape_len = reshape_len;
- for (s = 0; s < seg->area_count; s++)
+ for (s = 0; s < seg->area_count; s++) {
+ RETURN_IF_ZERO(seg_type(seg, s) == AREA_LV, "sub lv");
first_seg(seg_lv(seg, s))->reshape_len = reshape_len;
+ }
return 1;
}
@@ -2202,9 +2207,7 @@ static int _lv_alloc_reshape_space(struct logical_volume *lv,
uint64_t data_offset, dev_sectors;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
/* Get data_offset and dev_sectors from the kernel */
if (!lv_raid_offset_and_sectors(lv, &data_offset, &dev_sectors)) {
@@ -2234,7 +2237,7 @@ PFLA("data_offset=%llu dev_sectors=%llu seg->reshape_len=%u out_of_place_les_per
return 0;
PFLA("lv->le_count=%u seg->len=%u seg->area_len=%u", lv->le_count, seg->len, seg->area_len);
-PFLA("images=%u area_count=%u reshape_len=%u", data_rimages, seg->area_count, reshape_len);
+PFLA("data_rimages=%u area_count=%u reshape_len=%u", data_rimages, seg->area_count, reshape_len);
PFLA("first_seg(seg_lv(seg, 0)->reshape_len=%u", first_seg(seg_lv(seg, 0))->reshape_len);
PFLA("first_seg(seg_lv(seg, 0)->len=%u", first_seg(seg_lv(seg, 0))->len);
if (!lv_extend(lv, seg->segtype, data_rimages,
@@ -2303,9 +2306,7 @@ static int _lv_free_reshape_space(struct logical_volume *lv)
struct lv_segment *seg;
PFL();
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
if (_reshape_len_per_dev(seg)) {
/*
@@ -2317,7 +2318,7 @@ PFL();
if (!_lv_alloc_reshape_space(lv, alloc_end, NULL))
return_0;
- /* Reset reshape lenght upfront lv_reduce() to allow it to set area_len ... properly */
+ /* Reset reshape length upfront lv_reduce() to allow it to set area_len ... properly */
if (!_lv_set_reshape_len(lv, 0))
return 0;
@@ -2339,7 +2340,8 @@ static struct lv_segment *_convert_lv_to_raid1(struct logical_volume *lv, const
struct lv_segment *seg;
uint64_t flags;
- RETURN_IF_ZERO(lv, "lv argument");
+ RETURN_IF_LV_SEG_ZERO(lv, first_seg(lv));
+
flags = RAID | LVM_READ | (lv->status & LVM_WRITE);
log_debug_metadata("Inserting layer lv on top of %s", display_lvname(lv));
@@ -2347,8 +2349,7 @@ static struct lv_segment *_convert_lv_to_raid1(struct logical_volume *lv, const
return NULL;
/* First segment has changed because of layer insertion */
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment after layer insertion");
+ RETURN_IF_ZERO((seg = first_seg(lv)), "lv raid segment after layer insertion");
seg->status |= SEG_RAID;
seg_lv(seg, 0)->status |= RAID_IMAGE | flags;
@@ -2370,19 +2371,30 @@ static struct lv_segment *_convert_lv_to_raid1(struct logical_volume *lv, const
static int _reset_flags_passed_to_kernel(struct logical_volume *lv, int *flag_cleared)
{
uint32_t s;
- struct lv_segment *seg = first_seg(lv);
+ struct logical_volume *slv;
+ struct lv_segment *seg;
uint64_t reset_flags = LV_REBUILD | LV_RESHAPE_DELTA_DISKS_PLUS | LV_RESHAPE_DELTA_DISKS_MINUS;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
*flag_cleared = 0;
- for (s = 0; s < seg->area_count; s++)
- if (seg_lv(seg, s)->status & reset_flags) {
- seg_lv(seg, s)->status &= ~reset_flags;
+ for (s = 0; s < seg->area_count; s++) {
+ RETURN_IF_ZERO(seg_type(seg, s) == AREA_LV, "sub image lv");
+ slv = seg_lv(seg, s);
+#if 1
+ if (slv->status & LV_RESHAPE_DELTA_DISKS_MINUS) {
+ slv->status |= LV_RESHAPE_REMOVED;
+ if (seg->meta_areas) {
+ RETURN_IF_ZERO(seg_metatype(seg, s) == AREA_LV, "sub meta lv");
+ seg_metalv(seg, s)->status |= LV_RESHAPE_REMOVED;
+ }
+ }
+#endif
+ if (slv->status & reset_flags) {
+ slv->status &= ~reset_flags;
*flag_cleared = 1;
}
+ }
if (seg->data_offset) {
seg->data_offset = 0;
@@ -2641,9 +2653,7 @@ static int _alloc_and_add_rmeta_devs_for_lv(struct logical_volume *lv)
struct lv_segment *seg;
struct dm_list meta_lvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
dm_list_init(&meta_lvs);
@@ -2684,9 +2694,7 @@ static int _raid0_add_or_remove_metadata_lvs(struct logical_volume *lv,
uint64_t raid_type_flag;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
if (seg->meta_areas) {
PFL();
@@ -2733,9 +2741,7 @@ static int _set_lv_areas_from_data_lvs_and_create_names(struct logical_volume *l
struct lv_list *lvl, *tlvl;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(data_lvs, "data lvs list argument");
dm_list_iterate_items_safe(lvl, tlvl, data_lvs) {
@@ -2771,14 +2777,14 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
uint32_t split_count;
struct lv_list *lvl;
struct dm_list meta_lvs, data_lvs;
- struct cmd_context *cmd = lv->vg->cmd;
+ struct cmd_context *cmd;
struct logical_volume *tracking, *split_lv = NULL;
struct lv_segment *seg;
struct dm_list tracking_pvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(split_name, "split name argument");
+ cmd = lv->vg->cmd;
dm_list_init(&meta_lvs);
dm_list_init(&data_lvs);
@@ -2942,9 +2948,7 @@ int lv_raid_split_and_track(struct logical_volume *lv,
int s;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
if (!seg_is_mirrored(seg)) {
log_error("Unable to split images from non-mirrored RAID");
@@ -3041,7 +3045,7 @@ int lv_raid_merge(struct logical_volume *image_lv)
}
lv = lvl->lv;
- seg = first_seg(lv);
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
if (!seg_is_raid1(seg)) {
log_error("%s is no RAID1 array - refusing to merge.",
@@ -3132,9 +3136,7 @@ static int _adjust_data_lvs(struct logical_volume *lv, enum mirror_raid_conv dir
{ 'm', MIRROR_IMAGE, RAID_IMAGE }
};
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
for (s = 0; s < seg->area_count; ++s) {
struct logical_volume *dlv = seg_lv(seg, s);
@@ -3171,9 +3173,7 @@ static int _convert_mirror_to_raid(struct logical_volume *lv,
{
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(new_segtype, "new segment type argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
if (!seg_is_mirrored(seg)) {
log_error(INTERNAL_ERROR "mirror conversion supported only");
@@ -3215,7 +3215,7 @@ static int _convert_mirror_to_raid(struct logical_volume *lv,
if (new_image_count != seg->area_count) {
log_debug_metadata("Changing image count to %u on %s",
new_image_count, display_lvname(lv));
- if (!_lv_change_image_count(lv, new_segtype, new_image_count, allocate_pvs, removal_lvs))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, removal_lvs))
return 0;
}
@@ -3238,9 +3238,7 @@ static int _convert_raid1_to_mirror(struct logical_volume *lv,
{
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(new_segtype, "new segment type argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
if (!seg_is_raid1(seg)) {
log_error(INTERNAL_ERROR "raid1 conversion supported only");
@@ -3264,7 +3262,7 @@ static int _convert_raid1_to_mirror(struct logical_volume *lv,
if (new_image_count != seg->area_count) {
log_debug_metadata("Changing image count to %u on %s",
new_image_count, display_lvname(lv));
- if (!_lv_change_image_count(lv, new_segtype, new_image_count, allocate_pvs, removal_lvs))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, removal_lvs))
return 0;
}
@@ -3371,10 +3369,9 @@ static int _lv_has_one_stripe_zone(struct logical_volume *lv)
struct lv_segment *seg;
unsigned area_count;
- RETURN_IF_ZERO(lv, "lv argument");
- RETURN_IF_ZERO(first_seg(lv), "lv raid segment");
- area_count = first_seg(lv)->area_count;
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
+ area_count = seg->area_count;
dm_list_iterate_items(seg, &lv->segments)
if (seg->area_count != area_count)
return 0;
@@ -3421,11 +3418,8 @@ static struct lv_segment *_convert_striped_to_raid0(struct logical_volume *lv,
struct segment_type *segtype;
struct dm_list data_lvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
- area_count = seg->area_count;
- RETURN_IF_ZERO(area_count, "now segment areas");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
+ RETURN_IF_ZERO((area_count = seg->area_count), "now segment areas");
if (!seg_is_striped(seg)) {
log_error(INTERNAL_ERROR "Cannot convert non-%s LV %s to %s",
@@ -3559,9 +3553,7 @@ static int _alloc_and_add_new_striped_segment(struct logical_volume *lv,
struct lv_segment *seg, *new_seg;
struct segment_type *striped_segtype;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(new_segments, "new segments argument");
if (!(striped_segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_STRIPED)))
@@ -3595,14 +3587,13 @@ static int _alloc_and_add_new_striped_segment(struct logical_volume *lv,
static int _raid0_to_striped_retrieve_segments_and_lvs(struct logical_volume *lv,
struct dm_list *removal_lvs)
{
- uint32_t s, area_le, area_len, le, le_count = lv->le_count;
+ uint32_t s, area_le, area_len, le, le_count;
struct lv_segment *data_seg, *seg, *seg_to;
struct dm_list new_segments;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
+ le_count = lv->le_count;
dm_list_init(&new_segments);
/*
@@ -3670,9 +3661,7 @@ static int _convert_raid0_to_striped(struct logical_volume *lv,
{
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
/* Caller should ensure, but... */
if (!seg_is_any_raid0(seg)) {
@@ -3751,7 +3740,11 @@ PFLA("kernel_devs=%u dev_count=%u", kernel_devs, dev_count);
return kernel_devs < dev_count ? 2 : 3;
}
-/* Return new length for @lv based on @old_image_count and @new_image_count in @*len */
+/*
+ * Return new length for @lv based on @old_image_count and @new_image_count in @*len
+ *
+ * Subtracts any reshape space and provide data lenght only!
+ */
static int _lv_reshape_get_new_len(struct logical_volume *lv,
uint32_t old_image_count, uint32_t new_image_count,
uint32_t *len)
@@ -3760,22 +3753,13 @@ static int _lv_reshape_get_new_len(struct logical_volume *lv,
uint32_t di_old, di_new;
uint64_t r;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(len, "reshape length argumen");
+ RETURN_IF_ZERO((di_old = _data_rimages_count(seg, old_image_count)), "new data images");
+ RETURN_IF_ZERO((di_new = _data_rimages_count(seg, new_image_count)), "new data images");
- di_old = _data_rimages_count(seg, old_image_count);
- RETURN_IF_ZERO(di_old, "data images old");
- di_new = _data_rimages_count(seg, new_image_count);
- RETURN_IF_ZERO(di_new, "data images new");
-
- r = seg->len - _reshape_len_per_dev(seg) * di_old;
-
- if ((r = r * di_new / di_old) > UINT_MAX) {
- log_error(INTERNAL_ERROR "New lenght is too large!");
- return 0;
- }
+ r = seg->len - _reshape_len_per_dev(seg) * di_old;
+ RETURN_IF_NONZERO((r = r * di_new / di_old) > UINT_MAX, "New length is too large!");
*len = (uint32_t) r;
@@ -3791,25 +3775,21 @@ static int _reshape_adjust_to_size(struct logical_volume *lv,
struct lv_segment *seg;
uint32_t lv_reshape_len;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
lv_reshape_len = _reshape_len_per_dev(seg) * _data_rimages_count(seg, new_image_count);
- if (_lv_reshape_get_new_len(lv, old_image_count, new_image_count, &seg->len))
+ if (!_lv_reshape_get_new_len(lv, old_image_count, new_image_count, &seg->len))
return 0;
+ seg->len += lv_reshape_len;
lv->le_count = seg->len;
lv->size = lv->le_count * lv->vg->extent_size;
- seg->len += lv_reshape_len;
- if (old_image_count < new_image_count)
+ if (old_image_count < new_image_count) {
_lv_set_reshape_len(lv, _reshape_len_per_dev(seg));
PFLA("seg->len=%u seg->area_len=%u seg->area_count=%u old_image_count=%u new_image_count=%u", seg->len, seg->area_len, seg->area_count, old_image_count, new_image_count);
-
- if (new_image_count > old_image_count) {
/* Extend from raid1 mapping */
if (old_image_count == 2 &&
!seg->stripe_size)
@@ -3841,22 +3821,19 @@ static int _raid_reshape(struct logical_volume *lv,
{
int r, too_few = 0;
unsigned devs_health, devs_in_sync;
- uint32_t new_len, s, old_dev_count, new_dev_count;
+ uint32_t active_lvs, new_image_count, new_len, s, old_image_count, reduce_len, removed_lvs;
+ uint64_t extend_len;
struct lv_segment *seg;
struct dm_list removal_lvs;
struct lvinfo info = { 0 };
- RETURN_IF_ZERO(lv, "lv argument");
- RETURN_IF_ZERO(new_segtype, "new segment type argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
- old_dev_count = seg->area_count;
- RETURN_IF_ZERO(old_dev_count , "old device count calculated");
- new_dev_count = new_stripes + seg->segtype->parity_devs;
- RETURN_IF_NONZERO(new_dev_count < 2, "raid set with less than parity devices");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
+ RETURN_IF_ZERO((old_image_count = seg->area_count), "old device count calculated");
+ RETURN_IF_NONZERO((new_image_count = new_stripes + seg->segtype->parity_devs) < 2,
+ "raid set with less than parity devices");
RETURN_IF_ZERO(allocate_pvs , "allocate pvs list argument");
-PFLA("old_dev_count=%u new_dev_count=%u", old_dev_count, new_dev_count);
+PFLA("old_image_count=%u new_image_count=%u", old_image_count, new_image_count);
dm_list_init(&removal_lvs);
if (!is_same_level(seg->segtype, new_segtype)) {
@@ -3871,7 +3848,7 @@ PFLA("old_dev_count=%u new_dev_count=%u", old_dev_count, new_dev_count);
}
if (seg->segtype == new_segtype &&
- old_dev_count == new_dev_count &&
+ old_image_count == new_image_count &&
seg->stripe_size == new_stripe_size) {
log_error(INTERNAL_ERROR "Nothing to do");
return 0;
@@ -3892,10 +3869,10 @@ PFLA("old_dev_count=%u new_dev_count=%u", old_dev_count, new_dev_count);
}
seg->stripe_size = new_stripe_size;
- switch ((r = _reshaped_state(lv, old_dev_count, &devs_health, &devs_in_sync))) {
+ switch ((r = _reshaped_state(lv, old_image_count, &devs_health, &devs_in_sync))) {
case 1:
/*
- * old_dev_count == kernel_dev_count
+ * old_image_count == kernel_dev_count
*
* Check for device health
*/
@@ -3908,15 +3885,15 @@ PFL();
break;
case 2:
-PFLA("devs_in_sync=%u old_dev_count=%u new_dev_count=%u", devs_in_sync,old_dev_count, new_dev_count);
- if (devs_in_sync == new_dev_count)
+PFLA("devs_in_sync=%u old_image_count=%u new_image_count=%u", devs_in_sync,old_image_count, new_image_count);
+ if (devs_in_sync == new_image_count)
break;
/* Possible after a shrinking reshape and forgotten device removal */
log_error("Device count is incorrect. "
"Forgotten \"lvconvert --stripes %d %s\" to remove %u images after reshape?",
devs_in_sync - seg->segtype->parity_devs, display_lvname(lv),
- old_dev_count - devs_in_sync);
+ old_image_count - devs_in_sync);
return 0;
default:
@@ -3925,53 +3902,62 @@ PFLA("devs_in_sync=%u old_dev_count=%u new_dev_count=%u", devs_in_sync,old_dev_c
}
/* Handle disk addition reshaping */
- if (old_dev_count < new_dev_count) {
+ if (old_image_count < new_image_count) {
PFL();
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) && driver_version(NULL, 0)) {
log_error("lv_info failed: aborting");
return 0;
}
- if (!_lv_reshape_get_new_len(lv, old_dev_count, new_dev_count, &new_len))
+ if (!_lv_reshape_get_new_len(lv, old_image_count, new_image_count, &new_len))
return 0;
+ reduce_len = seg->len - _data_rimages_count(seg, old_image_count);
log_warn("WARNING: Adding stripes to active%s logical volume %s will grow "
"it from %u to %u extents!\n"
"You may want to run \"lvresize -l%u %s\" to shrink it after\n"
"the conversion has finished or make use of the gained capacity",
info.open_count ? " and open" : "",
- display_lvname(lv), seg->len, new_len,
- seg->len, display_lvname(lv));
+ display_lvname(lv), reduce_len, new_len,
+ reduce_len, display_lvname(lv));
- if (!_yes_no_conversion(lv, new_segtype, yes, force, new_dev_count,
+ if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count,
seg->data_copies, new_stripes, new_stripe_size))
return 0;
/* Allocate new image component pairs for the additional stripes and grow LV size */
log_debug_metadata("Adding %u data and metadata image LV pair%s to %s",
- new_dev_count - old_dev_count, new_dev_count - old_dev_count > 1 ? "s" : "",
+ new_image_count - old_image_count, new_image_count - old_image_count > 1 ? "s" : "",
display_lvname(lv));
- if (!_lv_change_image_count(lv, new_segtype, new_dev_count, allocate_pvs, NULL))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, NULL))
return 0;
PFLA("seg->reshape_len=%u", _reshape_len_per_dev(seg));
for (s = 0; s < seg->area_count; s++)
-PFLA("first_seg(seg_lv(seg, %u)->reshape_len=%u", s, _reshape_len_per_dev(first_seg(seg_lv(seg, s))));
+PFLA("first_seg(seg_lv(seg, %u))->len=%u first_seg(seg_lv(seg, %u))->area_len=%u first_seg(seg_lv(seg, %u)->reshape_len=%u", s, first_seg(seg_lv(seg, s))->len, s, first_seg(seg_lv(seg, s))->area_len, s, _reshape_len_per_dev(first_seg(seg_lv(seg, s))));
/* Reshape adding image component pairs -> change sizes accordingly */
- if (!_reshape_adjust_to_size(lv, old_dev_count, new_dev_count))
+ if (!_reshape_adjust_to_size(lv, old_image_count, new_image_count)) {
+ log_error("Failed to adjust LV %s to new size!", display_lvname(lv));
return 0;
+ }
PFLA("seg->reshape_len=%u", _reshape_len_per_dev(seg));
for (s = 0; s < seg->area_count; s++)
-PFLA("first_seg(seg_lv(seg, %u)->reshape_len=%u", s, _reshape_len_per_dev(first_seg(seg_lv(seg, s))));
+PFLA("first_seg(seg_lv(seg, %u))->len=%u first_seg(seg_lv(seg, %u))->area_len=%u first_seg(seg_lv(seg, %u)->reshape_len=%u", s, first_seg(seg_lv(seg, s))->len, s, first_seg(seg_lv(seg, s))->area_len, s, _reshape_len_per_dev(first_seg(seg_lv(seg, s))));
+
/* Allocate forward out of place reshape space at the beginning of all data image LVs */
if (!_lv_alloc_reshape_space(lv, alloc_begin, allocate_pvs))
return 0;
+
+{
+struct lv_segment *seg1;
+
PFLA("seg->reshape_len=%u", _reshape_len_per_dev(seg));
for (s = 0; s < seg->area_count; s++)
-PFLA("first_seg(seg_lv(seg, %u)->reshape_len=%u", s, _reshape_len_per_dev(first_seg(seg_lv(seg, s))));
-
+dm_list_iterate_items(seg1, &seg_lv(seg, s)->segments)
+PFLA("%s seg1->len=%u seg1->area_len=%u seg1->reshape_len=%u", display_lvname(seg1->lv), seg1->len, seg1->area_len, _reshape_len_per_dev(seg1));
+}
/*
* Reshape adding image component pairs:
*
@@ -3980,7 +3966,7 @@ PFLA("first_seg(seg_lv(seg, %u)->reshape_len=%u", s, _reshape_len_per_dev(first_
*/
log_debug_metadata("Setting delta disk flag on new data LVs of %s",
display_lvname(lv));
- for (s = old_dev_count; s < seg->area_count; s++) {
+ for (s = old_image_count; s < seg->area_count; s++) {
PFLA("seg_lv(seg, %u)=%s", s, seg_lv(seg, s)->name);
seg_lv(seg, s)->status &= ~LV_REBUILD;
seg_lv(seg, s)->status |= LV_RESHAPE_DELTA_DISKS_PLUS;
@@ -3990,8 +3976,8 @@ PFLA("seg_lv(seg, %u)=%s", s, seg_lv(seg, s)->name);
log_warn("Ignoring layout change on device adding reshape");
/* Handle disk removal reshaping */
- } else if (old_dev_count > new_dev_count) {
- switch (_reshaped_state(lv, new_dev_count, &devs_health, &devs_in_sync)) {
+ } else if (old_image_count > new_image_count) {
+ switch (_reshaped_state(lv, new_image_count, &devs_health, &devs_in_sync)) {
case 3:
/*
* Disk removal reshape step 1:
@@ -4007,9 +3993,12 @@ PFL();
return 0;
}
- new_len = _data_rimages_count(seg, new_dev_count) *
- (seg->len / _data_rimages_count(seg, old_dev_count));
-PFLA("new_dev_count=%u _data_rimages_count(seg, new_dev_count)=%u new_len=%u", new_dev_count, _data_rimages_count(seg, new_dev_count), new_len);
+ if (!_lv_reshape_get_new_len(lv, old_image_count, new_image_count, &new_len))
+ return 0;
+
+ extend_len = seg->len - seg->reshape_len * _data_rimages_count(seg, old_image_count);
+ extend_len = extend_len * extend_len / new_len;
+PFLA("new_image_count=%u _data_rimages_count(seg, new_image_count)=%u new_len=%u", new_image_count, _data_rimages_count(seg, new_image_count), new_len);
log_warn("WARNING: Removing stripes from active%s logical volume %s will shrink "
"it from %s to %s!",
info.open_count ? " and open" : "", display_lvname(lv),
@@ -4017,7 +4006,7 @@ PFLA("new_dev_count=%u _data_rimages_count(seg, new_dev_count)=%u new_len=%u", n
display_size(lv->vg->cmd, new_len * lv->vg->extent_size));
log_warn("THIS MAY DESTROY (PARTS OF) YOUR DATA!");
log_warn("You may want to interrupt the conversion and run \"lvresize -y -l%u %s\" ",
- (uint32_t) ((uint64_t) seg->len * seg->len / new_len), display_lvname(lv));
+ (uint32_t) extend_len, display_lvname(lv));
log_warn("to keep the current size if you haven't done it already");
log_warn("If that leaves the logical volume larger than %u extents due to stripe rounding,",
new_len);
@@ -4026,7 +4015,7 @@ PFLA("new_dev_count=%u _data_rimages_count(seg, new_dev_count)=%u new_len=%u", n
new_stripes, display_lvname(lv));
log_warn("in order to remove the freed up stripes from the raid set");
- if (!_yes_no_conversion(lv, new_segtype, yes, force, new_dev_count,
+ if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count,
seg->data_copies, new_stripes, new_stripe_size))
return 0;
@@ -4035,10 +4024,6 @@ PFLA("new_dev_count=%u _data_rimages_count(seg, new_dev_count)=%u new_len=%u", n
return 0;
}
- /* Reshape removing image component pairs -> change sizes accordingly */
- if (!_reshape_adjust_to_size(lv, old_dev_count, new_dev_count))
- return 0;
-
/*
* Allocate backward out of place reshape space at the
* _end_ of all data image LVs, because MD reshapes backwards
@@ -4047,9 +4032,17 @@ PFLA("new_dev_count=%u _data_rimages_count(seg, new_dev_count)=%u new_len=%u", n
if (!_lv_alloc_reshape_space(lv, alloc_end, allocate_pvs))
return 0;
- for (s = new_dev_count; s < old_dev_count; s++)
+ /* Flag all disks past new images as delta disks minus to kernel */
+ for (s = new_image_count; s < old_image_count; s++)
seg_lv(seg, s)->status |= LV_RESHAPE_DELTA_DISKS_MINUS;
+#if 0
+ /* Reshape removing image component pairs -> change sizes accordingly */
+ if (!_reshape_adjust_to_size(lv, old_image_count, new_image_count)) {
+ log_error("Failed to adjust LV %s to new size!", display_lvname(lv));
+ return 0;
+ }
+#endif
if (seg->segtype != new_segtype)
log_warn("Ignoring layout change on device removing reshape");
@@ -4066,10 +4059,30 @@ PFLA("new_dev_count=%u _data_rimages_count(seg, new_dev_count)=%u new_len=%u", n
*
*/
PFL();
+ for (active_lvs = removed_lvs = s = 0; s < seg->area_count; s++) {
+ struct logical_volume *slv;
+
+ RETURN_IF_NONZERO(seg_type(seg, s) != AREA_LV ||
+ !(slv = seg_lv(seg, s)), "image sub lv");
+ if (slv->status & LV_RESHAPE_REMOVED)
+ removed_lvs++;
+ else
+ active_lvs++;
+ }
+
+ RETURN_IF_ZERO(devs_in_sync == active_lvs, "correct kernel/lvm active lv count");
+ RETURN_IF_ZERO(active_lvs + removed_lvs == old_image_count, "correct kernel/lvm total lv count");
+
+ /* Reshape removing image component pairs -> change sizes accordingly */
+ if (!_reshape_adjust_to_size(lv, old_image_count, new_image_count)) {
+ log_error("Failed to adjust LV %s to new size!", display_lvname(lv));
+ return 0;
+ }
+
log_debug_metadata("Removing %u data and metadata image LV pair%s from %s",
- old_dev_count - new_dev_count, old_dev_count - new_dev_count > 1 ? "s" : "",
+ old_image_count - new_image_count, old_image_count - new_image_count > 1 ? "s" : "",
display_lvname(lv));
- if (!_lv_change_image_count(lv, new_segtype, new_dev_count, allocate_pvs, &removal_lvs))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, &removal_lvs))
return 0;
break;
@@ -4083,7 +4096,7 @@ PFL();
/* Handle raid set layout reshaping (e.g. raid5_ls -> raid5_n) */
} else {
PFL();
- if (!_yes_no_conversion(lv, new_segtype, yes, force, new_dev_count,
+ if (!_yes_no_conversion(lv, new_segtype, yes, force, new_image_count,
seg->data_copies, new_stripes, new_stripe_size))
return 0;
PFL();
@@ -4132,10 +4145,7 @@ static int _reshape_requested(const struct logical_volume *lv, const struct segm
{
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- RETURN_IF_ZERO(segtype, "segment type argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), segtype);
PFL();
/* This segment type is not reshapable */
@@ -4532,9 +4542,7 @@ static int _log_possible_conversion_types(struct logical_volume *lv, const struc
const struct segment_type *segtype;
const struct possible_type *pt;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
/* Get any possible_type entry for @seg to check for any segtype flags it is possible to convert to */
if (!(pt = _get_possible_type(seg, NULL, 0))) {
@@ -4753,8 +4761,7 @@ static int function_name(TAKEOVER_FN_ARGUMENTS, struct dm_list *removal_lvs)
/* Noop takeover handler for @lv: logs that LV already is of the requested type */
TAKEOVER_FN(_noop)
{
- RETURN_IF_ZERO(lv, "lv argument");
- RETURN_IF_ZERO(first_seg(lv), "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, first_seg(lv));
log_warn("Logical volume %s already is of requested type %s",
display_lvname(lv), lvseg_name(first_seg(lv)));
@@ -4765,16 +4772,11 @@ TAKEOVER_FN(_noop)
/* Error takeover handler for @lv: logs what's (im)possible to convert to (and mabye added later) */
TAKEOVER_FN(_error)
{
- struct lv_segment *seg;
-
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
- RETURN_IF_ZERO(new_segtype, "new segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
log_error("Converting the segment type for %s (directly) from %s to %s"
" is not supported (yet).", display_lvname(lv),
- lvseg_name(seg), new_segtype->name);
+ lvseg_name(first_seg(lv)), new_segtype->name);
log_error("You may want to use the \"--duplicate\" option");
return 0;
@@ -4943,9 +4945,7 @@ static int __rename_sub_lvs(struct logical_volume *lv, enum rename_dir dir, uint
{ "_dup_", "_split_" } },
}, *ft;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(seg->area_count, "lv segment areas");
switch (dir) {
@@ -5017,9 +5017,7 @@ static int _get_max_sub_lv_name_index(struct logical_volume *lv, uint32_t *max_i
uint32_t s, idx;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(max_idx, "max index argument");
RETURN_IF_ZERO(seg->area_count, "lv segment areas");
@@ -5046,9 +5044,7 @@ static int _prepare_seg_for_name_shift(struct logical_volume *lv)
uint32_t idx, max_idx;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(seg->area_count, "lv segment areas");
if (!_get_max_sub_lv_name_index(lv, &max_idx))
@@ -5093,9 +5089,7 @@ static int _raid_split_duplicate(struct logical_volume *lv, const char *split_na
struct lv_segment *seg;
struct logical_volume *split_lv;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(split_name, "split name argument");
RETURN_IF_ZERO(seg->area_count, "lv segment areas");
@@ -5296,10 +5290,7 @@ static int _raid_conv_unduplicate(struct logical_volume *lv,
struct logical_volume *lv_tmp;
struct lv_segment *seg, *seg0;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
- RETURN_IF_ZERO(segtype, "lv segment type argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), segtype);
RETURN_IF_ZERO(seg->area_count, "lv segment areas");
RETURN_IF_ZERO(data_copies, "data copies argument");
@@ -5449,9 +5440,7 @@ static int _raid_conv_duplicate(struct logical_volume *lv,
struct lv_segment *seg;
const char **lv_name_sav;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
/* new_segtype may be naught */
RETURN_IF_ZERO(seg->area_count, "lv segment areas");
RETURN_IF_ZERO(data_copies, "data copies argument");
@@ -5705,9 +5694,7 @@ TAKEOVER_HELPER_FN(_linear_raid0)
struct lv_segment *seg;
struct dm_list meta_lvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
RETURN_IF_ZERO(seg->area_count, "lv segment areas");
dm_list_init(&meta_lvs);
@@ -5760,9 +5747,7 @@ TAKEOVER_HELPER_FN(_linear_raid14510)
struct dm_list data_lvs, meta_lvs;
struct segment_type *segtype;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
RETURN_IF_ZERO(seg->area_count, "lv segment areas");
dm_list_init(&data_lvs);
@@ -5801,7 +5786,7 @@ TAKEOVER_HELPER_FN(_linear_raid14510)
/* Allocate the additional meta and data lvs requested */
log_debug_metadata("Allocating %u additional data and metadata image pairs for %s",
new_image_count - 1, display_lvname(lv));
- if (!_lv_change_image_count(lv, new_segtype, new_image_count, allocate_pvs, NULL))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, NULL))
return 0;
seg = first_seg(lv);
@@ -5815,9 +5800,7 @@ TAKEOVER_HELPER_FN(_striped_raid0_raid45610)
{
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
RETURN_IF_ZERO(seg->area_count > 1, "area count > 1");
PFLA("data_copies=%u", new_data_copies);
@@ -5874,7 +5857,7 @@ PFL();
if (!segtype_is_raid10_far(new_segtype)) {
/* Add the additional component LV pairs */
log_debug_metadata("Adding component LV pairs to %s", display_lvname(lv));
- if (!_lv_change_image_count(lv, new_segtype, new_image_count, allocate_pvs, NULL))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, NULL))
return 0;
}
PFL();
@@ -5959,9 +5942,7 @@ TAKEOVER_HELPER_FN(_raid0_linear)
struct lv_segment *seg;
struct dm_list removal_lvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
RETURN_IF_ZERO(seg->area_count == 1, "area count == 1");
dm_list_init(&removal_lvs);
@@ -5992,9 +5973,7 @@ TAKEOVER_HELPER_FN(_raid0_mirror)
struct lv_segment *seg;
struct segment_type *segtype;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
if (seg->area_count != 1)
return _error(lv, new_segtype, yes, force, 0, 0 /* data_copies */, 0, 0, NULL);
@@ -6043,9 +6022,7 @@ TAKEOVER_HELPER_FN(_raid0_raid1)
{
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
RETURN_IF_ZERO(seg_is_any_raid0(seg) && seg->area_count == 1,
"converson of non-raid0 LV or with area count != 1");
@@ -6073,7 +6050,7 @@ TAKEOVER_HELPER_FN(_raid0_raid1)
lvseg_name(seg), new_segtype->name,
new_image_count - seg->area_count);
seg->segtype = new_segtype;
- if (!_lv_change_image_count(lv, new_segtype, new_image_count, allocate_pvs, NULL))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, NULL))
return 0;
/* Master leg is the first sub lv */
@@ -6085,9 +6062,11 @@ TAKEOVER_HELPER_FN(_raid0_raid1)
/* Helper: mirror -> raid0* */
TAKEOVER_HELPER_FN(_mirror_raid0)
{
- struct lv_segment *seg = first_seg(lv);
+ struct lv_segment *seg;
struct dm_list removal_lvs;
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
+
dm_list_init(&removal_lvs);
if (!seg_is_mirrored(seg)) {
@@ -6130,9 +6109,7 @@ TAKEOVER_HELPER_FN(_mirror_r45)
struct lv_segment *seg;
struct dm_list removal_lvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
dm_list_init(&removal_lvs);
@@ -6178,9 +6155,7 @@ TAKEOVER_HELPER_FN(_raid1_raid0)
struct lv_segment *seg;
struct dm_list removal_lvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
dm_list_init(&removal_lvs);
@@ -6198,7 +6173,7 @@ TAKEOVER_HELPER_FN(_raid1_raid0)
return_0;
seg->segtype = new_segtype;
- if (!_lv_change_image_count(lv, new_segtype, 1, allocate_pvs, &removal_lvs))
+ if (!_lv_change_image_count(lv, 1, allocate_pvs, &removal_lvs))
return 0;
/* Remove rmeta last LV if raid0 */
@@ -6218,9 +6193,7 @@ TAKEOVER_HELPER_FN(_r456_r0_striped)
struct lv_segment *seg;
struct dm_list removal_lvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
PFLA("new_stripes=%u new_image_count=%u", new_stripes, new_image_count);
if (!seg_is_raid4(seg) && !seg_is_raid5_n(seg) && !seg_is_raid6_n_6(seg)) {
@@ -6249,7 +6222,7 @@ PFLA("new_stripes=%u new_image_count=%u", new_stripes, new_image_count);
}
/* Remove meta and data LVs requested */
- if (!_lv_change_image_count(lv, new_segtype, new_image_count, allocate_pvs, &removal_lvs))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, &removal_lvs))
return 0;
if (!(seg->segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID0_META)))
@@ -6275,9 +6248,7 @@ TAKEOVER_HELPER_FN(_raid14510_linear)
struct lv_segment *seg;
struct dm_list removal_lvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
dm_list_init(&removal_lvs);
PFL();
@@ -6310,7 +6281,7 @@ PFL();
/* Reduce image count to one */
if (!(seg->segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID1)) ||
- !_lv_change_image_count(lv, new_segtype, 1, allocate_pvs, &removal_lvs))
+ !_lv_change_image_count(lv, 1, allocate_pvs, &removal_lvs))
return 0;
if (!_convert_raid_to_linear(lv, &removal_lvs))
@@ -6325,9 +6296,7 @@ TAKEOVER_HELPER_FN(_raid145_raid1_raid6)
struct lv_segment *seg;
struct dm_list removal_lvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
dm_list_init(&removal_lvs);
@@ -6349,7 +6318,7 @@ TAKEOVER_HELPER_FN(_raid145_raid1_raid6)
if (!archive(lv->vg))
return_0;
- if (!_lv_change_image_count(lv, new_segtype, new_image_count, allocate_pvs, &removal_lvs))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, &removal_lvs))
return 0;
first_seg(lv)->segtype = new_segtype;
@@ -6368,9 +6337,7 @@ static int _adjust_raid10_far_lv_size(struct logical_volume *lv,
{
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(data_copies, "data_copies != 0 argument");
if (!seg_is_raid10_far(seg)) {
@@ -6396,9 +6363,7 @@ TAKEOVER_HELPER_FN(_raid145_raid4510)
{
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
if (!seg_is_raid1(seg) &&
!seg_is_raid4(seg) &&
@@ -6463,9 +6428,7 @@ TAKEOVER_HELPER_FN_REMOVAL_LVS(_raid10_striped_r0)
/* Save data_copies and le_count for raid10_far conversion */
uint32_t data_copies, le_count = lv->le_count;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
raid10_far = seg_is_raid10_far(seg);
data_copies = seg->data_copies;
@@ -6517,7 +6480,7 @@ TAKEOVER_HELPER_FN_REMOVAL_LVS(_raid10_striped_r0)
/* Remove the last half of the meta and data image pairs */
log_debug_metadata("Removing data and metadata image LV pairs from %s", display_lvname(lv));
- if (!_lv_change_image_count(lv, new_segtype, new_image_count, allocate_pvs, removal_lvs))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, removal_lvs))
return 0;
/* raid10_far: prepare properties to shrink lv size to striped/raid0* */
@@ -6564,9 +6527,7 @@ TAKEOVER_HELPER_FN(_raid10_r1456)
struct lv_segment *seg;
struct dm_list removal_lvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "lv segment argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
RETURN_IF_ZERO(seg->data_copies, "data copies > 0");
RETURN_IF_ZERO(new_segtype, "lv new segment type argument");
@@ -6620,7 +6581,7 @@ TAKEOVER_HELPER_FN(_raid10_r1456)
/* Linear -> raid0 */
TAKEOVER_FN(_l_r0)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _lv_has_segments_with_n_areas(lv, 1) &&
_linear_raid0(lv, new_segtype, yes, force, 1, 1, 0, 0, allocate_pvs);
@@ -6629,7 +6590,7 @@ TAKEOVER_FN(_l_r0)
/* Linear -> raid1 */
TAKEOVER_FN(_l_r1)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _lv_has_segments_with_n_areas(lv, 1) &&
_linear_raid14510(lv, new_segtype, yes, force,
@@ -6640,7 +6601,7 @@ TAKEOVER_FN(_l_r1)
/* Linear -> raid4/5 */
TAKEOVER_FN(_l_r45)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
if (!_lv_has_segments_with_n_areas(lv, 1))
return 0;
@@ -6653,7 +6614,7 @@ TAKEOVER_FN(_l_r45)
/* Linear -> raid10 */
TAKEOVER_FN(_l_r10)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _lv_has_segments_with_n_areas(lv, 1) &&
_linear_raid14510(lv, new_segtype, yes, force,
@@ -6664,7 +6625,7 @@ TAKEOVER_FN(_l_r10)
/* Striped -> raid0 */
TAKEOVER_FN(_s_r0)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
if (!_yes_no_conversion(lv, new_segtype, yes, force, 0, 0, 0, 0))
return 0;
@@ -6679,7 +6640,7 @@ TAKEOVER_FN(_s_r0)
/* Striped -> raid0_meta */
TAKEOVER_FN(_s_r0m)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
if (!_yes_no_conversion(lv, new_segtype, yes, force, 0, 0, 0, 0))
return 0;
@@ -6694,7 +6655,7 @@ TAKEOVER_FN(_s_r0m)
/* Striped -> raid4/5 */
TAKEOVER_FN(_s_r45)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 2 /* data_copies*/, 0, 0, allocate_pvs);
}
@@ -6702,14 +6663,14 @@ TAKEOVER_FN(_s_r45)
/* Striped -> raid6 */
TAKEOVER_FN(_s_r6)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 2, 3 /* data_copies*/, 0, 0, allocate_pvs);
}
TAKEOVER_FN(_s_r10)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count * new_data_copies, new_data_copies, 0, 0, allocate_pvs);
}
@@ -6717,7 +6678,7 @@ TAKEOVER_FN(_s_r10)
/* mirror -> raid0 */
TAKEOVER_FN(_m_r0)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _mirror_raid0(lv, new_segtype, yes, force, 1, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6725,7 +6686,7 @@ TAKEOVER_FN(_m_r0)
/* mirror -> raid0_meta */
TAKEOVER_FN(_m_r0m)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _mirror_raid0(lv, new_segtype, yes, force, 1, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6735,7 +6696,7 @@ TAKEOVER_FN(_m_r1)
{
struct dm_list removal_lvs;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
dm_list_init(&removal_lvs);
@@ -6753,7 +6714,7 @@ TAKEOVER_FN(_m_r1)
/* Mirror with 2 images -> raid4/5 */
TAKEOVER_FN(_m_r45)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _mirror_r45(lv, new_segtype, yes, force, 0, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6763,7 +6724,7 @@ TAKEOVER_FN(_m_r10)
{
struct lv_segment *seg;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
seg = first_seg(lv);
if (seg->area_count != 2) {
@@ -6791,7 +6752,7 @@ TAKEOVER_FN(_m_r10)
/* raid0 -> linear */
TAKEOVER_FN(_r0_l)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _raid0_linear(lv, new_segtype, yes, force, 0, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6799,7 +6760,7 @@ TAKEOVER_FN(_r0_l)
/* raid0 with one image -> mirror */
TAKEOVER_FN(_r0_m)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _raid0_mirror(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6807,7 +6768,7 @@ TAKEOVER_FN(_r0_m)
/* raid0 -> raid0_meta */
TAKEOVER_FN(_r0_r0m)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
/* Archive metadata */
if (!archive(lv->vg))
@@ -6821,7 +6782,7 @@ TAKEOVER_FN(_r0_s)
{
struct dm_list removal_lvs;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
dm_list_init(&removal_lvs);
@@ -6835,7 +6796,7 @@ TAKEOVER_FN(_r0_s)
/* raid0 with one image -> raid1 */
TAKEOVER_FN(_r0_r1)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _raid0_raid1(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6843,7 +6804,7 @@ TAKEOVER_FN(_r0_r1)
/* raid0 -> raid4/5_n */
TAKEOVER_FN(_r0_r45)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6851,7 +6812,7 @@ TAKEOVER_FN(_r0_r45)
/* raid0 -> raid6_n_6 */
TAKEOVER_FN(_r0_r6)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 2, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6859,7 +6820,7 @@ TAKEOVER_FN(_r0_r6)
/* raid0 with N images (N > 1) -> raid10 */
TAKEOVER_FN(_r0_r10)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count * new_data_copies, new_data_copies, 0, 0, allocate_pvs);
}
@@ -6867,7 +6828,7 @@ TAKEOVER_FN(_r0_r10)
/* raid0_meta -> */
TAKEOVER_FN(_r0m_l)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _raid0_linear(lv, new_segtype, yes, force, 0, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6875,7 +6836,7 @@ TAKEOVER_FN(_r0m_l)
/* raid0_meta -> mirror */
TAKEOVER_FN(_r0m_m)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _raid0_mirror(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6885,7 +6846,7 @@ TAKEOVER_FN(_r0m_r0)
{
struct dm_list removal_lvs;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
dm_list_init(&removal_lvs);
@@ -6901,7 +6862,7 @@ TAKEOVER_FN(_r0m_s)
{
struct dm_list removal_lvs;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
dm_list_init(&removal_lvs);
@@ -6915,7 +6876,7 @@ TAKEOVER_FN(_r0m_s)
/* raid0_meta wih 1 image -> raid1 */
TAKEOVER_FN(_r0m_r1)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _raid0_raid1(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6923,7 +6884,7 @@ TAKEOVER_FN(_r0m_r1)
/* raid0_meta -> raid4/5_n */
TAKEOVER_FN(_r0m_r45)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6931,7 +6892,7 @@ TAKEOVER_FN(_r0m_r45)
/* raid0_meta -> raid6_n_6 */
TAKEOVER_FN(_r0m_r6)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count + 2, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -6940,7 +6901,7 @@ TAKEOVER_FN(_r0m_r6)
/* raid0_meta wih 1 image -> raid10 */
TAKEOVER_FN(_r0m_r10)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _striped_raid0_raid45610(lv, new_segtype, yes, force, first_seg(lv)->area_count * new_data_copies, new_data_copies, 0, 0, allocate_pvs);
}
@@ -6949,7 +6910,7 @@ TAKEOVER_FN(_r0m_r10)
/* raid1 with N images -> linear */
TAKEOVER_FN(_r1_l)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
PFL();
return _raid14510_linear(lv, NULL, yes, force, 1, 1, 0, 0, allocate_pvs);
}
@@ -6957,7 +6918,7 @@ PFL();
/* raid1 with N images -> striped */
TAKEOVER_FN(_r1_s)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
PFL();
return _raid14510_linear(lv, NULL, yes, force, 1, 1, 0, 0, allocate_pvs);
}
@@ -6967,7 +6928,7 @@ TAKEOVER_FN(_r1_m)
{
struct dm_list removal_lvs;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
dm_list_init(&removal_lvs);
@@ -6999,7 +6960,7 @@ TAKEOVER_FN(_r1_m)
/* raid1 -> raid0 */
TAKEOVER_FN(_r1_r0)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _raid1_raid0(lv, new_segtype, yes, force, 1, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -7007,14 +6968,14 @@ TAKEOVER_FN(_r1_r0)
/* raid1 -> raid0_meta */
TAKEOVER_FN(_r1_r0m)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _raid1_raid0(lv, new_segtype, yes, force, 1, 0 /* data_copies */, 0, 0, allocate_pvs);
}
TAKEOVER_FN(_r1_r1)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _raid145_raid1_raid6(lv, new_segtype, yes, force, new_image_count, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -7022,7 +6983,7 @@ TAKEOVER_FN(_r1_r1)
/* raid1 with 2 legs -> raid4/5 */
TAKEOVER_FN(_r1_r45)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
if (first_seg(lv)->area_count != 2) {
log_error("Can't convert %s from %s to %s with != 2 images",
@@ -7038,7 +6999,7 @@ TAKEOVER_FN(_r1_r45)
/* raid1 with N legs or duplicating one -> raid10_near */
TAKEOVER_FN(_r1_r10)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
if (!segtype_is_raid10_near(new_segtype)) {
log_error("Conversion of %s to %s prohibited",
@@ -7053,7 +7014,7 @@ return _raid145_raid4510(lv, new_segtype, yes, force, new_image_count, 0 /* data
/* raid45 with 2 images -> linear */
TAKEOVER_FN(_r45_l)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
if (first_seg(lv)->area_count != 2) {
log_error("Can't convert %s from %s/%s to %s with != 2 images",
@@ -7068,7 +7029,7 @@ TAKEOVER_FN(_r45_l)
/* raid4/5 -> striped */
TAKEOVER_FN(_r45_s)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
PFL();
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -7076,7 +7037,7 @@ PFL();
/* raid4/5 with 2 images -> mirror */
TAKEOVER_FN(_r45_m)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _mirror_r45(lv, new_segtype, yes, force, 0, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -7084,7 +7045,7 @@ TAKEOVER_FN(_r45_m)
/* raid4/5 -> raid0 */
TAKEOVER_FN(_r45_r0)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -7092,7 +7053,7 @@ TAKEOVER_FN(_r45_r0)
/* raid4/5 -> raid0_meta */
TAKEOVER_FN(_r45_r0m)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -7102,9 +7063,8 @@ TAKEOVER_FN(_r45_r1)
{
struct lv_segment *seg;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
- seg = first_seg(lv);
if ((seg_is_raid5_n(seg) && seg->area_count != 3) ||
seg->area_count != 2) {
log_error("Can't convert %s from %s to %s with != %u images",
@@ -7122,9 +7082,8 @@ TAKEOVER_FN(_r45_r54)
struct lv_segment *seg;
const struct segment_type *segtype_sav = new_segtype;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
- seg = first_seg(lv);
if (!((seg_is_raid4(seg) && segtype_is_any_raid5(new_segtype)) ||
(seg_is_raid5_n(seg) && segtype_is_raid4(new_segtype)))) {
log_error(INTERNAL_ERROR "Called with %s -> %s on LV %s",
@@ -7150,9 +7109,8 @@ TAKEOVER_FN(_r45_r6)
{
struct lv_segment *seg;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
- seg = first_seg(lv);
if (seg_is_raid4(seg)) {
const struct segment_type *segtype_sav = new_segtype;
@@ -7189,7 +7147,7 @@ TAKEOVER_FN(_r45_r6)
/* raid6 -> striped */
TAKEOVER_FN(_r6_s)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -7197,7 +7155,7 @@ TAKEOVER_FN(_r6_s)
/* raid6 -> raid0 */
TAKEOVER_FN(_r6_r0)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -7205,7 +7163,7 @@ TAKEOVER_FN(_r6_r0)
/* raid6 -> raid0_meta */
TAKEOVER_FN(_r6_r0m)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return _r456_r0_striped(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2, 0 /* data_copies */, 0, 0, allocate_pvs);
}
@@ -7216,12 +7174,11 @@ TAKEOVER_FN(_r6_r45)
struct lv_segment *seg;
struct dm_list removal_lvs;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
if (!_raid_in_sync(lv))
return 0;
- seg = first_seg(lv);
if (segtype_is_raid4(new_segtype) &&
!seg_is_raid6_n_6(seg)) {
log_error("LV %s has to be of type %s to allow for this conversion",
@@ -7250,7 +7207,7 @@ TAKEOVER_FN(_r6_r45)
/* Remove meta and data lvs requested */
log_debug_metadata("Removing one data and metadata image LV pair from %s", display_lvname(lv));
- if (!_lv_change_image_count(lv, new_segtype, new_image_count, allocate_pvs, &removal_lvs))
+ if (!_lv_change_image_count(lv, new_image_count, allocate_pvs, &removal_lvs))
return 0;
if (segtype_is_raid4(new_segtype))
@@ -7267,7 +7224,7 @@ TAKEOVER_FN(_r6_r45)
/* raid10 with 2 images -> linear */
TAKEOVER_FN(_r10_l)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
if (first_seg(lv)->area_count != 2) {
log_error("Can't convert %s from %s to %s with != 2 images",
@@ -7283,7 +7240,7 @@ TAKEOVER_FN(_r10_s)
{
struct dm_list removal_lvs;
PFL();
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
dm_list_init(&removal_lvs);
@@ -7296,11 +7253,10 @@ TAKEOVER_FN(_r10_m)
struct lv_segment *seg;
struct dm_list removal_lvs;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
dm_list_init(&removal_lvs);
- seg = first_seg(lv);
if (seg->area_count != 2) {
log_error("Can't convert %s from %s to %s with != 2 images",
display_lvname(lv), SEG_TYPE_NAME_RAID10, SEG_TYPE_NAME_MIRROR);
@@ -7330,7 +7286,7 @@ TAKEOVER_FN(_r10_r0)
{
struct dm_list removal_lvs;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
dm_list_init(&removal_lvs);
@@ -7342,7 +7298,7 @@ TAKEOVER_FN(_r10_r0m)
{
struct dm_list removal_lvs;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
dm_list_init(&removal_lvs);
@@ -7354,9 +7310,7 @@ TAKEOVER_FN(_r10_r1)
{
struct lv_segment *seg;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
-
- seg = first_seg(lv);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
return ((seg_is_raid10_near(seg) && seg->data_copies == seg->area_count) ||
_lv_has_segments_with_n_areas(lv, 2)) &&
@@ -7379,7 +7333,7 @@ static int _lv_create_raid01_image_lvs(struct logical_volume *lv,
char *image_name;
struct logical_volume *image_lvs[data_copies];
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), segtype);
RETURN_IF_ZERO(image_extents, "image extents");
RETURN_IF_ZERO(stripes, "stripes");
RETURN_IF_ZERO(stripe_size, "stripe_size");
@@ -7456,11 +7410,9 @@ TAKEOVER_FN(_s_r01)
struct lv_segment *seg, *striped_seg;
PFLA("new_data_copies=%u", new_data_copies);
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (striped_seg = first_seg(lv)), new_segtype);
RETURN_IF_ZERO(new_data_copies > 1, "data copies > 1 argument");
PFL();
- striped_seg = first_seg(lv);
-
log_debug_metadata("Converting lv %s to raid1", display_lvname(lv));
if (!(seg = _convert_lv_to_raid1(lv, "_rimage_0")))
return 0;
@@ -7492,7 +7444,7 @@ PFL();
/* raid0 with any number of images to raid01 */
TAKEOVER_FN(_r0_r01)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return 0;
}
@@ -7500,7 +7452,7 @@ TAKEOVER_FN(_r0_r01)
/* raid0_meta with any number of images to raid01 */
TAKEOVER_FN(_r0m_r01)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return 0;
}
@@ -7512,8 +7464,7 @@ TAKEOVER_FN(_r01_s)
struct logical_volume *image_lv = NULL;
struct lv_segment *seg;
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
- seg = first_seg(lv);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
RETURN_IF_ZERO(seg->area_count, "segment areas");
for (s = 0; s < seg->area_count; s++)
@@ -7549,7 +7500,7 @@ PFL();
/* raid01 with any number of data_copies to raid0 */
TAKEOVER_FN(_r01_r0)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return 0;
}
@@ -7557,7 +7508,7 @@ TAKEOVER_FN(_r01_r0)
/* raid01 with any number of data_copies to raid0_meta */
TAKEOVER_FN(_r01_r0m)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return 0;
}
@@ -7565,7 +7516,7 @@ TAKEOVER_FN(_r01_r0m)
/* raid01 with any number of data_copies to raid45 */
TAKEOVER_FN(_r01_r45)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return 0;
@@ -7575,7 +7526,7 @@ TAKEOVER_FN(_r01_r45)
/* raid01 with any number of data_copies to raid10 */
TAKEOVER_FN(_r01_r10)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return 0;
}
@@ -7583,7 +7534,7 @@ TAKEOVER_FN(_r01_r10)
/* Change number of data_copies on raid01 */
TAKEOVER_FN(_r01_r01)
{
- RETURN_LV_SEG_SEGTYPE_NAUGHT(lv, first_seg(lv), new_segtype);
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), new_segtype);
return 0;
}
@@ -7643,13 +7594,14 @@ static int _conversion_options_allowed(const struct lv_segment *seg_from,
{
int r = 1;
uint32_t opts;
- const struct segment_type *new_segtype = segtype_to;
+ const struct segment_type *new_segtype;
struct cmd_context *cmd;
RETURN_IF_ZERO(seg_from, "segment from argument");
RETURN_IF_ZERO(segtype_to, "segment type argument");
cmd = seg_from->lv->vg->cmd;
+ new_segtype = segtype_to;
if (seg_is_striped(seg_from) ||
seg_is_any_raid0(seg_from) ||
@@ -7908,7 +7860,7 @@ PFLA("new_segtype=%s image_count=%u data_copies=%u stripes=%u", new_segtype ? ne
return 0;
}
- if ((new_data_copies || new_stripes) &&
+ if ((new_data_copies > 1 || new_stripes) &&
seg->segtype != new_segtype) {
log_error("Can't reshape and takeover %s at the same time",
display_lvname(lv));
@@ -7987,7 +7939,7 @@ static uint32_t _extents_needed_to_repair(struct logical_volume *lv, struct dm_l
{
uint32_t r = 0;
- RETURN_IF_ZERO(lv, "lv argument");
+ RETURN_IF_LV_SEG_ZERO(lv, first_seg(lv));
RETURN_IF_ZERO(remove_pvs, "remove pvs list argument");
if ((lv->status & PARTIAL_LV) &&
@@ -8015,7 +7967,7 @@ static int _try_to_replace_whole_lv(struct logical_volume *lv, struct dm_list *r
{
uint32_t extents_needed;
- RETURN_IF_ZERO(lv, "lv argument");
+ RETURN_IF_LV_SEG_ZERO(lv, first_seg(lv));
RETURN_IF_ZERO(remove_pvs, "remove pvs list argument");
/* First, get the extents needed to replace @lv */
@@ -8066,9 +8018,7 @@ static int _remove_partial_multi_segment_image(struct logical_volume *lv,
uint32_t s;
struct lv_segment *raid_seg;
- RETURN_IF_ZERO(lv, "lv argument");
- raid_seg = first_seg(lv);
- RETURN_IF_ZERO(raid_seg, "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (raid_seg = first_seg(lv)));
RETURN_IF_ZERO(raid_seg->area_count, "no raid segment areas");
RETURN_IF_ZERO(remove_pvs, "remove pvs list argument");
@@ -8100,9 +8050,7 @@ static int _generate_name_and_set_segment(struct logical_volume *lv,
struct lv_list *lvl;
const char *suffix;
- RETURN_IF_ZERO(lv, "lv argument");
- raid_seg = first_seg(lv);
- RETURN_IF_ZERO(raid_seg, "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (raid_seg = first_seg(lv)));
RETURN_IF_ZERO(raid_seg->area_count, "no raid segment areas");
RETURN_IF_ZERO(lvs, "no lvs list");
RETURN_IF_NONZERO(dm_list_empty(lvs), "no lvs listed");
@@ -8134,7 +8082,7 @@ static int __sub_lv_needs_rebuilding(struct logical_volume *slv,
{
int r = 0;
- RETURN_IF_ZERO(slv, "slv argument");
+ RETURN_IF_LV_SEG_ZERO(slv, first_seg(slv));
RETURN_IF_ZERO(remove_pvs, "remove pvs list argument");
RETURN_IF_ZERO(partial_lvs, "partial lvs argument");
@@ -8193,9 +8141,7 @@ int lv_raid_replace(struct logical_volume *lv,
struct lv_segment *raid_seg;
struct lv_list *lvl;
- RETURN_IF_ZERO(lv, "lv argument");
- raid_seg = first_seg(lv);
- RETURN_IF_ZERO(raid_seg, "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (raid_seg = first_seg(lv)));
RETURN_IF_ZERO(remove_pvs, "remove pvs list argument");
RETURN_IF_ZERO(partial_lvs, "partial lvs argument");
@@ -8557,6 +8503,7 @@ static int _pv_on_list(struct physical_volume *pv, struct dm_list *failed_pvs)
RETURN_IF_ZERO(pv, "pv argument");
RETURN_IF_ZERO(failed_pvs, "failed pvs list argument");
+ /* failed_ps may be empty initially */
dm_list_iterate_items(pvl, failed_pvs)
if (pvl->pv == pv)
@@ -8580,6 +8527,7 @@ static int _add_pv_to_failed_pvs(struct physical_volume *pv, struct dm_list *fai
RETURN_IF_ZERO(pv, "pv argument");
RETURN_IF_ZERO(failed_pvs, "failed pvs list argument");
+ /* failed_ps may be empty initially */
if (_pv_on_list(pv, failed_pvs))
return 0;
@@ -8628,12 +8576,11 @@ static int _find_failed_pvs_of_lv(struct logical_volume *lv,
uint32_t s;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(failed_pvs, "failed pvs list argument");
RETURN_IF_ZERO(failed_rimage, "failed rimage argument");
RETURN_IF_ZERO(failed_rmeta, "failed rmeta argument");
+ RETURN_IF_ZERO(seg->area_count, "segment areas");
if (_lv_is_duplicating(lv)) {
for (s = 0; s < seg->area_count; s++)
@@ -8667,8 +8614,7 @@ static int _replace_raid_lv_with_error_segment(struct logical_volume *lv,
struct dm_list *failed_pvs,
uint32_t *replaced_lvs)
{
- RETURN_IF_ZERO(lv, "lv argument");
- RETURN_IF_ZERO(first_seg(lv), "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, first_seg(lv));
RETURN_IF_ZERO(failed_pvs, "failed pvs list argument");
RETURN_IF_ZERO(replaced_lvs, "replaced lvs argument");
@@ -8699,9 +8645,7 @@ static int _replace_lvs_on_failed_pvs_with_error_segments(struct logical_volume
uint32_t s;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(failed_pvs, "failed pvs list argument");
RETURN_IF_ZERO(replaced_lvs, "replaced lvs argument");
@@ -8732,9 +8676,7 @@ int lv_raid_remove_missing(struct logical_volume *lv)
struct lv_segment *seg;
struct dm_list failed_pvs;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
dm_list_init(&failed_pvs);
PFL();
@@ -8795,7 +8737,7 @@ PFLA("failed_rimage=%u failed_rmeta=%u max_failed=%u", failed_rimage, failed_rme
/* Return 1 if @lv has failed */
static int _lv_has_failed(struct logical_volume *lv)
{
- RETURN_IF_ZERO(lv, "lv argument");
+ RETURN_IF_LV_SEG_ZERO(lv, first_seg(lv));
return (lv->status & PARTIAL_LV) ||
lv_is_virtual(lv);
@@ -8807,9 +8749,7 @@ static int _partial_raid_lv_is_redundant(const struct logical_volume *lv)
struct lv_segment *raid_seg;
uint32_t failed_rimage = 0, failed_rmeta = 0, min_devs, s;
- RETURN_IF_ZERO(lv, "lv argument");
- raid_seg = first_seg(lv);
- RETURN_IF_ZERO(raid_seg, "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (raid_seg = first_seg(lv)));
min_devs = raid_seg->segtype->parity_devs ?: 1;
@@ -8819,11 +8759,17 @@ static int _partial_raid_lv_is_redundant(const struct logical_volume *lv)
* dev (mandatory unless raid0) and quorum number of data devs
*/
for (s = 0; s < raid_seg->area_count; s++) {
+ RETURN_IF_ZERO(seg_type(raid_seg, s) == AREA_LV, "data sub lv");
+
if (_lv_has_failed(seg_lv(raid_seg, s)))
failed_rimage++;
- if (raid_seg->meta_areas && _lv_has_failed(seg_lv(raid_seg, s)))
- failed_rmeta++;
+ if (raid_seg->meta_areas) {
+ RETURN_IF_ZERO(seg_metatype(raid_seg, s) == AREA_LV, "meta sub lv");
+
+ if (_lv_has_failed(seg_lv(raid_seg, s)))
+ failed_rmeta++;
+ }
}
/* No devices failed -> fully redundant */
@@ -8939,7 +8885,7 @@ int partial_raid_lv_supports_degraded_activation(const struct logical_volume *cl
int not_capable = 0;
struct logical_volume *lv;
- RETURN_IF_ZERO(clv, "clv argument");
+ RETURN_IF_LV_SEG_ZERO(clv, first_seg(clv));
lv = (struct logical_volume*) clv; /* drop const */
@@ -8972,7 +8918,7 @@ static int _raid10_seg_images_sane(struct lv_segment *seg)
if (!len) {
len = seg_lv(seg, 0)->le_count;
if (!len) {
- log_error(INTERNAL_ERROR "raid10_far segment area %u with LV %s has 0 lenght!",
+ log_error(INTERNAL_ERROR "raid10_far segment area %u with LV %s has 0 length!",
s, display_lvname(seg->lv));
return 0;
}
@@ -9004,9 +8950,7 @@ static int _split_lv_data_images(struct logical_volume *lv,
uint32_t s;
struct lv_segment *seg;
- RETURN_IF_ZERO(lv, "lv argument");
- seg = first_seg(lv);
- RETURN_IF_ZERO(seg, "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_ZERO(seg->area_count, "segment areas");
RETURN_IF_ZERO(split_len < seg->len, "suitable agument split_len");
@@ -9040,9 +8984,7 @@ int lv_raid10_far_reorder_segments(struct logical_volume *lv, uint32_t extents,
struct logical_volume *slv;
struct lv_segment *seg, *raid_seg;
- RETURN_IF_ZERO(lv, "lv argument");
- raid_seg = first_seg(lv);
- RETURN_IF_ZERO(raid_seg, "raid segment");
+ RETURN_IF_LV_SEG_ZERO(lv, (raid_seg = first_seg(lv)));
RETURN_IF_ZERO(extents, "extents");
/* We may only reorder in case of raid10 far */
@@ -9152,14 +9094,15 @@ int lv_create_raid01(struct logical_volume *lv, const struct segment_type *segty
uint64_t status = RAID_IMAGE | LVM_READ | LVM_WRITE;
struct lv_segment *raid1_seg;
struct segment_type *image_segtype;
- struct volume_group *vg = lv->vg;
+ struct volume_group *vg;
- RETURN_IF_ZERO(lv, "lv argument");
- RETURN_IF_ZERO(segtype, "segtype argument");
+ RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, first_seg(lv), segtype);
RETURN_IF_ZERO(extents, "extents");
RETURN_IF_ZERO(allocate_pvs, "allocate pvs argument");
RETURN_IF_NONZERO(dm_list_empty(allocate_pvs), "allocate pvs list empyte");
+ vg = lv->vg;
+
PFLA("data_copies=%u region_size=%u stripes=%u stripe_size=%u", data_copies, region_size, stripes, stripe_size);
if (data_copies < 2 || stripes < 2)
return 0;
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 71a57ddc1..61639afc7 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -164,7 +164,8 @@ FIELD(VGS, vg, SIZ, "VMdaSize", cmd, 9, vgmdasize, vg_mda_size, "Size of smalles
FIELD(VGS, vg, NUM, "#VMdaCps", cmd, 8, vgmdacopies, vg_mda_copies, "Target number of in use metadata areas in the VG.", 1)
FIELD(SEGS, seg, STR, "Type", list, 4, segtype, segtype, "Type of LV segment.", 0)
-FIELD(SEGS, seg, NUM, "#Str", area_count, 4, uint32, stripes, "Number of total stripes or mirror/raid1 legs.", 0)
+// FIELD(SEGS, seg, NUM, "#Str", area_count, 4, uint32, stripes, "Number of total stripes or mirror/raid1 legs.", 0)
+FIELD(SEGS, seg, NUM, "#Str", list, 5, seg_stripes, stripes, "Number of data stripes or mirror/raid1 legs.", 0)
FIELD(SEGS, seg, NUM, "#DStr", list, 5, segdata_stripes, datastripes, "Number of data stripes or mirror/raid1 legs.", 0)
FIELD(SEGS, seg, NUM, "#DStr", list, 5, segdata_stripes, data_stripes, "Number of data stripes or mirror/raid1 legs.", 0)
FIELD(SEGS, seg, NUM, "SRes", list, 4, segreshape_len, reshape_len, "Number of reshape extents.", 0)
diff --git a/lib/report/report.c b/lib/report/report.c
index 3dad43ee9..f8a7ae8e1 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1990,12 +1990,34 @@ static int _segmonitor_disp(struct dm_report *rh, struct dm_pool *mem,
GET_FIELD_RESERVED_VALUE(seg_monitor_undef));
}
+static int _get_seg_used_stripes(const struct lv_segment *seg)
+{
+ uint32_t s;
+ uint32_t stripes = seg->area_count;
+
+ for (s = seg->area_count - 1; s; s--)
+ if (seg_type(seg, s) == AREA_LV &&
+ (seg_lv(seg, s)->status & LV_RESHAPE_REMOVED))
+ stripes--;
+
+ return stripes;
+}
+
+static int _seg_stripes_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ uint32_t stripes = _get_seg_used_stripes((const struct lv_segment *) data);
+
+ return dm_report_field_uint32(rh, field, &stripes);
+}
+
static int _segdata_stripes_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
const struct lv_segment *seg = (const struct lv_segment *) data;
- uint32_t stripes = seg->area_count - seg->segtype->parity_devs;
+ uint32_t stripes = _get_seg_used_stripes(seg) - seg->segtype->parity_devs;
return dm_report_field_uint32(rh, field, &stripes);
}
@@ -2112,7 +2134,10 @@ static int _segsizepe_disp(struct dm_report *rh,
const struct lv_segment *seg = (const struct lv_segment *) data;
if (seg) {
- uint32_t len = seg->len - seg->reshape_len * (seg->area_count - seg->segtype->parity_devs);
+ uint32_t len = seg->len;
+
+ if (seg->area_count > 1)
+ len -= seg->reshape_len * (seg->area_count - seg->segtype->parity_devs);
return dm_report_field_uint32(rh, field, &len);
}
@@ -3111,6 +3136,8 @@ static int _lvhealthstatus_disp(struct dm_report *rh, struct dm_pool *mem,
health = "mismatches exist";
} else if (lv->status & LV_WRITEMOSTLY)
health = "writemostly";
+ else if (lv->status & LV_RESHAPE_REMOVED)
+ health = "reshape removed";
} else if (lv_is_thin_pool(lv) && (lvdm->seg_status.type != SEG_STATUS_NONE)) {
if (lvdm->seg_status.type != SEG_STATUS_THIN_POOL)
return _field_set_value(field, GET_FIRST_RESERVED_NAME(health_undef),