diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 803f76052..81346bd1a 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -5456,15 +5456,27 @@ static int _lvresize_adjust_extents(struct logical_volume *lv, seg_last = last_seg(lv); - /* FIXME Support LVs with mixed segment types */ - if (lp->segtype && (lp->segtype != seg_last->segtype)) { - log_error("VolumeType does not match (%s).", lp->segtype->name); - return 0; + if (!lp->segtype) + /* Use segment type of last segment */ + lp->segtype = seg_last->segtype; + else if (lp->segtype != seg_last->segtype) { + /* Support newseg error or zero with lastseg striped + * and newseg striped with lastseg error or zero */ + if ((segtype_is_error(lp->segtype) || segtype_is_zero(lp->segtype) || + segtype_is_striped(lp->segtype)) && + (segtype_is_striped(seg_last->segtype) || + segtype_is_error(seg_last->segtype) || segtype_is_zero(seg_last->segtype))) { + if (!lp->stripes) + lp->stripes = 1; + } else { + log_error("VolumeType does not match (%s).", lp->segtype->name); + return 0; + } + /* FIXME Support more LVs with mixed segment types */ + log_print_unless_silent("Logical volume %s is using mixing segment types %s and %s.", + display_lvname(lv), seg_last->segtype->name, lp->segtype->name); } - /* Use segment type of last segment */ - lp->segtype = seg_last->segtype; - /* For virtual devices, just pretend the physical size matches. */ existing_physical_extents = saved_existing_physical_extents = _lv_pe_count(lv); if (!existing_physical_extents) { diff --git a/tools/lvresize.c b/tools/lvresize.c index a3c17a744..f39f03a40 100644 --- a/tools/lvresize.c +++ b/tools/lvresize.c @@ -20,9 +20,17 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv, { const char *cmd_name = command_name(cmd); const char *type_str = arg_str_value(cmd, type_ARG, NULL); + int only_linear = 0; - if (type_str && !(lp->segtype = get_segtype_from_string(cmd, type_str))) - return_0; + if (type_str) { + if (!strcmp(type_str, "linear")) { + type_str = "striped"; + only_linear = 1; /* User requested linear only target */ + } + + if (!(lp->segtype = get_segtype_from_string(cmd, type_str))) + return_0; + } if (!strcmp(cmd_name, "lvreduce")) lp->resize = LV_REDUCE; @@ -137,6 +145,11 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv, return 0; } + if (only_linear && lp->stripes > 1) { + log_error("Cannot use stripes with linear type."); + return 0; + } + if ((lp->stripe_size = arg_uint64_value(cmd, stripesize_ARG, 0)) && (arg_sign_value(cmd, stripesize_ARG, SIGN_NONE) == SIGN_MINUS)) { log_error("Stripesize may not be negative.");