mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
thin: support unaligned size of external origin and thin pool
With thin-pool kernel target module 1.13 it's now support usage of external origin with sizes which are not 'alligned' with chunk size of thin-pool. Enable lvm2 support for this and also fix reporting of data_percent usage for case sizes are not alligned.
This commit is contained in:
parent
6f2a617c31
commit
a3e0d830bd
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.122 -
|
Version 2.02.122 -
|
||||||
=================================
|
=================================
|
||||||
|
Support thins with size of external origin unaligned with thin pool chunk.
|
||||||
Allow to extend reduced thin volumes with external origins.
|
Allow to extend reduced thin volumes with external origins.
|
||||||
Consider snapshot and origin LV as unusable if its component is suspended.
|
Consider snapshot and origin LV as unusable if its component is suspended.
|
||||||
Fix lvmconfig segfault on settings with undefined default value (2.02.120).
|
Fix lvmconfig segfault on settings with undefined default value (2.02.120).
|
||||||
|
@ -243,12 +243,11 @@ int pool_supports_external_origin(const struct lv_segment *pool_seg, const struc
|
|||||||
{
|
{
|
||||||
uint32_t csize = pool_seg->chunk_size;
|
uint32_t csize = pool_seg->chunk_size;
|
||||||
|
|
||||||
if ((external_lv->size < csize) || (external_lv->size % csize)) {
|
if (((external_lv->size < csize) || (external_lv->size % csize)) &&
|
||||||
/* TODO: Validate with thin feature flag once, it will be supported */
|
!thin_pool_feature_supported(pool_seg->lv, THIN_FEATURE_EXTERNAL_ORIGIN_EXTEND)) {
|
||||||
log_error("Can't use \"%s/%s\" as external origin with \"%s/%s\" pool. "
|
log_error("Can't use \"%s\" as external origin with \"%s\" pool. "
|
||||||
"Size %s is not a multiple of pool's chunk size %s.",
|
"Size %s is not a multiple of pool's chunk size %s.",
|
||||||
external_lv->vg->name, external_lv->name,
|
display_lvname(external_lv), display_lvname(pool_seg->lv),
|
||||||
pool_seg->lv->vg->name, pool_seg->lv->name,
|
|
||||||
display_size(external_lv->vg->cmd, external_lv->size),
|
display_size(external_lv->vg->cmd, external_lv->size),
|
||||||
display_size(external_lv->vg->cmd, csize));
|
display_size(external_lv->vg->cmd, csize));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -609,14 +609,18 @@ static int _thin_target_percent(void **target_state __attribute__((unused)),
|
|||||||
uint64_t *total_denominator)
|
uint64_t *total_denominator)
|
||||||
{
|
{
|
||||||
struct dm_status_thin *s;
|
struct dm_status_thin *s;
|
||||||
|
uint64_t csize;
|
||||||
|
|
||||||
/* Status for thin device is in sectors */
|
/* Status for thin device is in sectors */
|
||||||
if (!dm_get_status_thin(mem, params, &s))
|
if (!dm_get_status_thin(mem, params, &s))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (seg) {
|
if (seg) {
|
||||||
*percent = dm_make_percent(s->mapped_sectors, seg->lv->size);
|
/* Pool allocates whole chunk so round-up to nearest one */
|
||||||
*total_denominator += seg->lv->size;
|
csize = first_seg(seg->pool_lv)->chunk_size;
|
||||||
|
csize = ((seg->lv->size + csize - 1) / csize) * csize;
|
||||||
|
*percent = dm_make_percent(s->mapped_sectors, csize);
|
||||||
|
*total_denominator += csize;
|
||||||
} else {
|
} else {
|
||||||
/* No lv_segment info here */
|
/* No lv_segment info here */
|
||||||
*percent = DM_PERCENT_INVALID;
|
*percent = DM_PERCENT_INVALID;
|
||||||
@ -645,8 +649,8 @@ static int _thin_target_present(struct cmd_context *cmd,
|
|||||||
{ 1, 4, THIN_FEATURE_BLOCK_SIZE, "block_size" },
|
{ 1, 4, THIN_FEATURE_BLOCK_SIZE, "block_size" },
|
||||||
{ 1, 5, THIN_FEATURE_DISCARDS_NON_POWER_2, "discards_non_power_2" },
|
{ 1, 5, THIN_FEATURE_DISCARDS_NON_POWER_2, "discards_non_power_2" },
|
||||||
{ 1, 10, THIN_FEATURE_METADATA_RESIZE, "metadata_resize" },
|
{ 1, 10, THIN_FEATURE_METADATA_RESIZE, "metadata_resize" },
|
||||||
{ 9, 11, THIN_FEATURE_EXTERNAL_ORIGIN_EXTEND, "external_origin_extend" },
|
|
||||||
{ 1, 10, THIN_FEATURE_ERROR_IF_NO_SPACE, "error_if_no_space" },
|
{ 1, 10, THIN_FEATURE_ERROR_IF_NO_SPACE, "error_if_no_space" },
|
||||||
|
{ 1, 13, THIN_FEATURE_EXTERNAL_ORIGIN_EXTEND, "external_origin_extend" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char _lvmconf[] = "global/thin_disabled_features";
|
static const char _lvmconf[] = "global/thin_disabled_features";
|
||||||
|
90
test/shell/lvcreate-thin-external-size.sh
Normal file
90
test/shell/lvcreate-thin-external-size.sh
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Copyright (C) 2015 Red Hat, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
# of the GNU General Public License v.2.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
# Test unaligned size of external origin and thin pool chunk size
|
||||||
|
|
||||||
|
export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
|
||||||
|
|
||||||
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
|
which cmp || skip
|
||||||
|
|
||||||
|
#
|
||||||
|
# Main
|
||||||
|
#
|
||||||
|
aux have_thin 1 3 0 || skip
|
||||||
|
|
||||||
|
aux prepare_pvs 2 640
|
||||||
|
|
||||||
|
# Use 8K extent size
|
||||||
|
vgcreate $vg -s 8K $(cat DEVICES)
|
||||||
|
|
||||||
|
# Prepare some numeric pattern with ~64K size
|
||||||
|
seq -s ' ' -w 0 10922 > 64K
|
||||||
|
|
||||||
|
d1="$DM_DEV_DIR/$vg/$lv1"
|
||||||
|
d2="$DM_DEV_DIR/$vg/$lv2"
|
||||||
|
|
||||||
|
# Prepare external origin LV with size not being a multiple of thin pool chunk size
|
||||||
|
lvcreate -l47 -n $lv1 $vg
|
||||||
|
|
||||||
|
# Fill end with pattern
|
||||||
|
dd if=64K of="$d1" bs=8192 seek=45 count=2
|
||||||
|
|
||||||
|
# Switch to read-only volume
|
||||||
|
lvchange -an $vg/$lv1
|
||||||
|
lvchange -pr $vg/$lv1
|
||||||
|
|
||||||
|
lvcreate -L2M -T $vg/pool -c 192K
|
||||||
|
lvcreate -s $vg/$lv1 --name $lv2 --thinpool $vg/pool
|
||||||
|
|
||||||
|
# Check the tail of $lv2 matches $lv1
|
||||||
|
dd if="$d2" of=16K bs=8192 skip=45 count=2
|
||||||
|
cmp -n 16384 -l 64K 16K
|
||||||
|
|
||||||
|
# Now extend and rewrite
|
||||||
|
lvextend -l+2 $vg/$lv2
|
||||||
|
|
||||||
|
dd if=64K of="$d2" bs=8192 seek=46 count=3 oflag=direct
|
||||||
|
dd if="$d2" of=24K bs=8192 skip=46 count=3 iflag=direct
|
||||||
|
cmp -n 24576 -l 64K 24K
|
||||||
|
|
||||||
|
# Consumes 2 192K chunks -> 66.67%
|
||||||
|
check lv_field $vg/$lv2 data_percent "66.67"
|
||||||
|
|
||||||
|
lvreduce -f -l-24 $vg/$lv2
|
||||||
|
|
||||||
|
dd if=64K of="$d2" bs=8192 seek=24 count=1 oflag=direct
|
||||||
|
dd if="$d2" of=8K bs=8192 skip=24 count=1 iflag=direct
|
||||||
|
cmp -n 8192 -l 64K 8K
|
||||||
|
|
||||||
|
# Check extension still works
|
||||||
|
lvextend -l+2 $vg/$lv2
|
||||||
|
|
||||||
|
lvremove -f $vg/pool
|
||||||
|
|
||||||
|
lvcreate -L256M -T $vg/pool -c 64M
|
||||||
|
lvcreate -s $vg/$lv1 --name $lv2 --thinpool $vg/pool
|
||||||
|
lvextend -l+2 $vg/$lv2
|
||||||
|
|
||||||
|
dd if=64K of="$d2" bs=8192 seek=45 count=4 oflag=direct
|
||||||
|
dd if="$d2" of=32K bs=8192 skip=45 count=4 iflag=direct
|
||||||
|
cmp -n 32768 -l 64K 32K
|
||||||
|
|
||||||
|
lvextend -L+64M $vg/$lv2
|
||||||
|
|
||||||
|
# Consumes 64M chunk -> 50%
|
||||||
|
check lv_field $vg/$lv2 data_percent "50.00"
|
||||||
|
|
||||||
|
vgremove -ff $vg
|
Loading…
Reference in New Issue
Block a user