mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-02 01:18:26 +03:00
thin: validate external origin size
Avoid use of external origin with size unaligned/incompatible with thin pool chunk size, since the last chunk is not correctly provisioned when it is overwritten.
This commit is contained in:
parent
8074d8056a
commit
155405b0e1
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.106 -
|
Version 2.02.106 -
|
||||||
====================================
|
====================================
|
||||||
|
Prohibit use of external origin with size incompatible with thin pool.
|
||||||
Avoid trying to convert single to thin pool and volume at the same time.
|
Avoid trying to convert single to thin pool and volume at the same time.
|
||||||
Add support for partitions on ZFS zvol.
|
Add support for partitions on ZFS zvol.
|
||||||
Fix unwanted drop of hold flocks on forked children.
|
Fix unwanted drop of hold flocks on forked children.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@ -5980,6 +5980,8 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
|
|||||||
* within the same thin pool
|
* within the same thin pool
|
||||||
*/
|
*/
|
||||||
if (lp->snapshot && (first_seg(org)->pool_lv != pool_lv)) {
|
if (lp->snapshot && (first_seg(org)->pool_lv != pool_lv)) {
|
||||||
|
if (!pool_supports_external_origin(first_seg(pool_lv), org))
|
||||||
|
return_0;
|
||||||
if (org->status & LVM_WRITE) {
|
if (org->status & LVM_WRITE) {
|
||||||
log_error("Cannot use writable LV as the external origin.");
|
log_error("Cannot use writable LV as the external origin.");
|
||||||
return 0; // TODO conversion for inactive
|
return 0; // TODO conversion for inactive
|
||||||
|
@ -682,6 +682,7 @@ uint64_t extents_from_size(struct cmd_context *cmd, uint64_t size,
|
|||||||
|
|
||||||
struct logical_volume *find_pool_lv(const struct logical_volume *lv);
|
struct logical_volume *find_pool_lv(const struct logical_volume *lv);
|
||||||
int pool_is_active(const struct logical_volume *pool_lv);
|
int pool_is_active(const struct logical_volume *pool_lv);
|
||||||
|
int pool_supports_external_origin(const struct lv_segment *pool_seg, const struct logical_volume *external_lv);
|
||||||
int thin_pool_feature_supported(const struct logical_volume *pool_lv, int feature);
|
int thin_pool_feature_supported(const struct logical_volume *pool_lv, int feature);
|
||||||
int update_pool_lv(struct logical_volume *lv, int activate);
|
int update_pool_lv(struct logical_volume *lv, int activate);
|
||||||
int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profile,
|
int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profile,
|
||||||
|
@ -252,6 +252,27 @@ int pool_below_threshold(const struct lv_segment *pool_seg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate given external origin could be used with thin pool
|
||||||
|
*/
|
||||||
|
int pool_supports_external_origin(const struct lv_segment *pool_seg, const struct logical_volume *external_lv)
|
||||||
|
{
|
||||||
|
uint32_t csize = pool_seg->chunk_size;
|
||||||
|
|
||||||
|
if ((external_lv->size < csize) || (external_lv->size % csize)) {
|
||||||
|
/* TODO: Validate with thin feature flag once, it will be supported */
|
||||||
|
log_error("Can't use \"%s/%s\" as external origin with \"%s/%s\" pool. "
|
||||||
|
"Size %s is not a multiple of pool's chunk size %s.",
|
||||||
|
external_lv->vg->name, external_lv->name,
|
||||||
|
pool_seg->lv->vg->name, pool_seg->lv->name,
|
||||||
|
display_size(external_lv->vg->cmd, external_lv->size),
|
||||||
|
display_size(external_lv->vg->cmd, csize));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
struct logical_volume *find_pool_lv(const struct logical_volume *lv)
|
struct logical_volume *find_pool_lv(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
struct lv_segment *seg;
|
struct lv_segment *seg;
|
||||||
|
@ -561,6 +561,8 @@ static int _thin_add_target_line(struct dev_manager *dm,
|
|||||||
|
|
||||||
/* Add external origin LV */
|
/* Add external origin LV */
|
||||||
if (seg->external_lv) {
|
if (seg->external_lv) {
|
||||||
|
if (!pool_supports_external_origin(first_seg(seg->pool_lv), seg->external_lv))
|
||||||
|
return_0;
|
||||||
if (seg->external_lv->size < seg->lv->size) {
|
if (seg->external_lv->size < seg->lv->size) {
|
||||||
/* Validate target supports smaller external origin */
|
/* Validate target supports smaller external origin */
|
||||||
if (!_thin_target_present(cmd, first_seg(seg->pool_lv), &attr) ||
|
if (!_thin_target_present(cmd, first_seg(seg->pool_lv), &attr) ||
|
||||||
|
@ -2483,6 +2483,9 @@ static int _lvconvert_thinpool_external(struct cmd_context *cmd,
|
|||||||
|
|
||||||
dm_list_init(&lvc.tags);
|
dm_list_init(&lvc.tags);
|
||||||
|
|
||||||
|
if (!pool_supports_external_origin(first_seg(pool_lv), external_lv))
|
||||||
|
return_0;
|
||||||
|
|
||||||
if (!(lvc.segtype = get_segtype_from_string(cmd, "thin")))
|
if (!(lvc.segtype = get_segtype_from_string(cmd, "thin")))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user