1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

Adjust region and stripe sizes on small VG extents

This commit is contained in:
Heinz Mauelshagen 2016-08-26 12:35:08 +02:00
parent 2aeb71cb37
commit ddb3826523
5 changed files with 24 additions and 17 deletions

View File

@ -1229,6 +1229,8 @@ static uint32_t _calc_area_multiple(const struct segment_type *segtype,
}
/*
* FIXME:
*
* RAID10 - only has 2-way mirror right now.
* If we are to move beyond 2-way RAID10, then
* the 'stripes' argument will always need to
@ -1256,14 +1258,14 @@ static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
uint32_t area_reduction, s;
/* Caller must ensure exact divisibility */
if (seg_is_striped(seg)) {
if (seg_is_striped(seg) || (seg_is_raid(seg) && !seg_is_raid1(seg))) {
if (reduction % seg->area_count) {
log_error("Segment extent reduction %" PRIu32
" not divisible by #stripes %" PRIu32,
reduction, seg->area_count);
return 0;
}
area_reduction = (reduction / seg->area_count);
area_reduction = (reduction / (seg->area_count - seg->segtype->parity_devs));
} else
area_reduction = reduction;
@ -3875,8 +3877,8 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
if (seg_is_raid(seg)) {
stripes = 1;
stripe_size = 0;
if (seg_is_any_raid0(seg))
area_multiple = seg->area_count;
area_multiple = _calc_area_multiple(seg->segtype, seg->area_count, seg_is_raid1(seg) ? 1 : seg->area_count - seg->segtype->parity_devs);
printf("area_multiple=%u\n", area_multiple);
}
for (fa = first_area, s = 0; s < seg->area_count; s++) {
@ -4000,7 +4002,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
}
/* Adjust region and stripe size on very small LVs */
static void _lv_adjust_region_and_stripe_size(struct logical_volume *lv)
void lv_adjust_region_and_stripe_size(struct logical_volume *lv)
{
uint32_t size;
struct lv_segment *seg = first_seg(lv);
@ -4135,7 +4137,7 @@ int lv_extend(struct logical_volume *lv,
stripe_size, 0u, 0)))
stack;
if (empty)
_lv_adjust_region_and_stripe_size(lv);
lv_adjust_region_and_stripe_size(lv);
} else {
/*
* For RAID, all the devices are AREA_LV.
@ -4162,7 +4164,7 @@ int lv_extend(struct logical_volume *lv,
goto_out;
if (empty)
_lv_adjust_region_and_stripe_size(lv);
lv_adjust_region_and_stripe_size(lv);
if (!(r = _raid_rmeta_size_sufficient(lv))) {
if (!old_extents &&

View File

@ -415,7 +415,6 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
area_multiplier = segtype_is_striped(seg->segtype) ?
seg->area_count : 1;
if (seg->area_len * area_multiplier != seg->len) {
log_error("LV %s: segment %u has inconsistent "
"area_len %u",

View File

@ -30,10 +30,11 @@
#define MAX_STRIPES 128U
#define SECTOR_SHIFT 9L
#define SECTOR_SIZE ( 1L << SECTOR_SHIFT )
#define STRIPE_SIZE_MIN 2 /* 2 sectors minimum */
#define STRIPE_SIZE_MIN 8 /* 8 sectors minimum to allow for raid takover of striped */
#define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define STRIPE_SIZE_LIMIT ((UINT_MAX >> 2) + 1)
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
#define MIN_EXTENT_SIZE 8 /* 8 sectors minimum to allow for raid takover of striped */
#define MAX_EXTENT_SIZE ((uint32_t) -1)
#define MIN_NON_POWER2_EXTENT_SIZE (128U * 2U) /* 128KB in sectors */
@ -825,6 +826,7 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv,
/* Updates and reloads metadata for given lv */
int lv_update_and_reload(struct logical_volume *lv);
int lv_update_and_reload_origin(struct logical_volume *lv);
void lv_adjust_region_and_stripe_size(struct logical_volume *lv);
uint32_t extents_from_size(struct cmd_context *cmd, uint64_t size,
uint32_t extent_size);

View File

@ -1008,6 +1008,11 @@ int vgcreate_params_validate(struct cmd_context *cmd,
return 0;
}
if (vp->extent_size < MIN_EXTENT_SIZE) {
log_error("Physical extent size < 4 KiB restricts RAID use.");
return 0;
}
if (!(cmd->fmt->features & FMT_UNLIMITED_VOLS)) {
if (!vp->max_lv)
vp->max_lv = 255;

View File

@ -651,6 +651,7 @@ static int _alloc_image_components(struct logical_volume *lv,
if (!region_size)
region_size = get_default_region_size(lv->vg->cmd);
if (seg_is_raid(seg))
if (seg_is_raid(seg))
segtype = seg->segtype;
else if (!(segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_RAID1)))
@ -2985,6 +2986,11 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
return 0;
}
/* FIXME Hard-coded raid0/4/5/6 */
/* Be prepared for any image addition -> raid5/6 */
if (seg_is_any_raid0(seg))
seg->area_len = seg->extents_copied = seg->len / seg->area_count;
/* Add the additional component LV pairs */
log_debug_metadata("Adding %" PRIu32 " component LV pair(s) to %s", new_image_count - lv_raid_image_count(lv),
display_lvname(lv));
@ -2999,10 +3005,9 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
seg->segtype = new_segtype;
seg->region_size = new_region_size;
/* FIXME Hard-coded raid0 to raid4 */
seg->area_len = seg->len;
_check_and_adjust_region_size(lv);
lv_adjust_region_and_stripe_size(lv);
log_debug_metadata("Updating VG metadata and reloading %s LV %s",
lvseg_name(seg), display_lvname(lv));
@ -3411,12 +3416,6 @@ static int _set_convenient_raid456_segtype_to(const struct lv_segment *seg_from,
!segtype_is_raid5_n(*segtype)) {
log_error("Conversion to raid5_n not yet supported.");
return 0;
/* If this is any raid6 conversion request -> enforce raid6_n_6, because we convert from striped */
} else if (segtype_is_any_raid6(*segtype) &&
!segtype_is_raid6_n_6(*segtype)) {
log_error("Conversion to raid6_n_6 not yet supported.");
return 0;
}
/* Got to do check for raid5 -> raid6 ... */