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 -
|
||||
====================================
|
||||
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.
|
||||
Add support for partitions on ZFS zvol.
|
||||
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) 2004-2013 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
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) {
|
||||
log_error("Cannot use writable LV as the external origin.");
|
||||
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);
|
||||
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 update_pool_lv(struct logical_volume *lv, int activate);
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 lv_segment *seg;
|
||||
|
@ -561,6 +561,8 @@ static int _thin_add_target_line(struct dev_manager *dm,
|
||||
|
||||
/* Add external origin 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) {
|
||||
/* Validate target supports smaller external origin */
|
||||
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);
|
||||
|
||||
if (!pool_supports_external_origin(first_seg(pool_lv), external_lv))
|
||||
return_0;
|
||||
|
||||
if (!(lvc.segtype = get_segtype_from_string(cmd, "thin")))
|
||||
return_0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user