From 3a82490ee1cf7aec5b2d6648f9bc74d9791eca8e Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Mon, 17 Mar 2014 13:04:14 +0100 Subject: [PATCH] snapshot: wrap min_chunk test into a lib function Create a separate function to validation snapshot min chunk value and relocate code into snapshot_manip file. This function will be shared with lvconvert then. --- lib/metadata/lv_manip.c | 13 ++----------- lib/metadata/metadata-exported.h | 1 + lib/metadata/snapshot_manip.c | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 9246920d2..6e4ba71c0 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -49,8 +49,6 @@ typedef enum { #define A_CAN_SPLIT 0x10 #define A_AREA_COUNT_MATCHES 0x20 /* Existing lvseg has same number of areas as new segment */ -#define SNAPSHOT_MIN_CHUNKS 3 /* Minimum number of chunks in snapshot */ - /* * Constant parameters during a single allocation attempt. */ @@ -6054,15 +6052,8 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, } if (lp->snapshot && !seg_is_thin(lp) && - (((uint64_t)lp->extents * vg->extent_size) < - (SNAPSHOT_MIN_CHUNKS * lp->chunk_size))) { - log_error("Unable to create a snapshot smaller than " - DM_TO_STRING(SNAPSHOT_MIN_CHUNKS) " chunks (%u extents, %s).", - (unsigned) (((uint64_t) SNAPSHOT_MIN_CHUNKS * lp->chunk_size + - vg->extent_size - 1) / vg->extent_size), - display_size(cmd, (uint64_t) SNAPSHOT_MIN_CHUNKS * lp->chunk_size)); - return NULL; - } + !cow_has_min_chunks(vg, lp->extents, lp->chunk_size)) + return NULL; if (!seg_is_virtual(lp) && vg->free_count < lp->extents && !lp->approx_alloc) { diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index 87e604658..347e080af 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -903,6 +903,7 @@ int lv_is_cow(const struct logical_volume *lv); int lv_is_merging_origin(const struct logical_volume *origin); int lv_is_merging_cow(const struct logical_volume *snapshot); uint32_t cow_max_extents(const struct logical_volume *origin, uint32_t chunk_size); +int cow_has_min_chunks(const struct volume_group *vg, uint32_t cow_extents, uint32_t chunk_size); int lv_is_cow_covering_origin(const struct logical_volume *lv); /* Test if given LV is visible from user's perspective */ diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c index 8fcab0c70..a0a3e3c10 100644 --- a/lib/metadata/snapshot_manip.c +++ b/lib/metadata/snapshot_manip.c @@ -21,6 +21,8 @@ #include "lv_alloc.h" #include "activate.h" +#define SNAPSHOT_MIN_CHUNKS 3 /* Minimum number of chunks in snapshot */ + int lv_is_origin(const struct logical_volume *lv) { return lv->origin_count ? 1 : 0; @@ -88,6 +90,20 @@ uint32_t cow_max_extents(const struct logical_volume *origin, uint32_t chunk_siz return (uint32_t) (size / extent_size); } +int cow_has_min_chunks(const struct volume_group *vg, uint32_t cow_extents, uint32_t chunk_size) +{ + if (((uint64_t)vg->extent_size * cow_extents) >= (SNAPSHOT_MIN_CHUNKS * chunk_size)) + return 1; + + log_error("Snapshot volume cannot be smaller than " DM_TO_STRING(SNAPSHOT_MIN_CHUNKS) + " chunks (%u extents, %s).", (unsigned) + (((uint64_t) SNAPSHOT_MIN_CHUNKS * chunk_size + + vg->extent_size - 1) / vg->extent_size), + display_size(vg->cmd, (uint64_t) SNAPSHOT_MIN_CHUNKS * chunk_size)); + + return 0; +} + int lv_is_cow_covering_origin(const struct logical_volume *lv) { return lv_is_cow(lv) &&