1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

thin: validate resize of thin LV with ext. origin

When thin volume is using external origin, current thin target
is not able to supply 'extended' size with empty pages.

lvm2 detects version and disables extension of LV past the external
origin size in this case.

Thin LV could be however still reduced and extended freely bellow
this size.
This commit is contained in:
Zdenek Kabelac 2014-01-23 13:10:29 +01:00
parent 2dae78b722
commit 902b343e0e
5 changed files with 22 additions and 0 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.106 -
====================================
Detect thin feature external_origin_extend and limit extend when missing.
Rename internal pool_can_resize_metadata() to thin_pool_feature_supported().
Issue error if libbblkid detects signature and fails to return offset/length.
Update autoconf config.guess/sub to 2014-01-01.

View File

@ -691,6 +691,7 @@ global {
# discards_non_power_2
# external_origin
# metadata_resize
# external_origin_extend
#
# thin_disabled_features = [ "discards", "block_size" ]
}

View File

@ -64,6 +64,7 @@ enum {
THIN_FEATURE_BLOCK_SIZE = (1 << 3),
THIN_FEATURE_DISCARDS_NON_POWER_2 = (1 << 4),
THIN_FEATURE_METADATA_RESIZE = (1 << 5),
THIN_FEATURE_EXTERNAL_ORIGIN_EXTEND = (1 << 6),
};
void set_activation(int activation);

View File

@ -2452,6 +2452,14 @@ int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
lv->le_count += extents;
lv->size += (uint64_t) extents *lv->vg->extent_size;
/* Validate thin target supports bigger size of thin volume then external origin */
if (lv_is_thin_volume(lv) && first_seg(lv)->external_lv &&
first_seg(lv)->external_lv->size < lv->size &&
!thin_pool_feature_supported(first_seg(lv)->pool_lv, THIN_FEATURE_EXTERNAL_ORIGIN_EXTEND)) {
log_error("Thin target does not support external origin smaller then thin volume.");
return 0;
}
return 1;
}

View File

@ -528,6 +528,7 @@ static int _thin_add_target_line(struct dev_manager *dm,
{
char *pool_dlid, *external_dlid;
uint32_t device_id = seg->device_id;
unsigned attr;
if (!seg->pool_lv) {
log_error(INTERNAL_ERROR "Segment %s has no pool.",
@ -560,6 +561,15 @@ static int _thin_add_target_line(struct dev_manager *dm,
/* Add external origin LV */
if (seg->external_lv) {
if (seg->external_lv->size < seg->lv->size) {
/* Validate target supports smaller external origin */
if (!_thin_target_present(cmd, first_seg(seg->pool_lv), &attr) ||
!(attr & THIN_FEATURE_EXTERNAL_ORIGIN_EXTEND)) {
log_error("Thin target does not support smaller size of external origin LV %s.",
seg->external_lv->name);
return 0;
}
}
if (!(external_dlid = build_dm_uuid(mem, seg->external_lv->lvid.s,
lv_layer(seg->external_lv)))) {
log_error("Failed to build uuid for external origin LV %s.",
@ -619,6 +629,7 @@ static int _thin_target_present(struct cmd_context *cmd,
{ 1, 4, THIN_FEATURE_BLOCK_SIZE, "block_size" },
{ 1, 5, THIN_FEATURE_DISCARDS_NON_POWER_2, "discards_non_power_2" },
{ 1, 10, THIN_FEATURE_METADATA_RESIZE, "metadata_resize" },
{ 9, 11, THIN_FEATURE_EXTERNAL_ORIGIN_EXTEND, "external_origin_extend" },
};
static const char _lvmconf[] = "global/thin_disabled_features";