diff options
author | Zdenek Kabelac <zkabelac@redhat.com> | 2013-03-11 12:37:09 +0100 |
---|---|---|
committer | Zdenek Kabelac <zkabelac@redhat.com> | 2013-03-13 15:13:54 +0100 |
commit | b36a776a7fed84fa6228ffa287b4c9ccdf355ddf (patch) | |
tree | f27b14dca70a81f8298adda5c02d1318eb5b5842 /lib | |
parent | f06dd8725a85d344820eda91835c58f489097563 (diff) | |
download | lvm2-b36a776a7fed84fa6228ffa287b4c9ccdf355ddf.tar.gz |
thin: move update_pool_params
Now we may recongnize preset arguments, move
the code for updating thin pool related values
into /lib portion of the code.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/metadata/metadata-exported.h | 4 | ||||
-rw-r--r-- | lib/metadata/thin_manip.c | 88 |
2 files changed, 92 insertions, 0 deletions
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index 5ed8f3ec9..c2728d500 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -576,6 +576,10 @@ uint64_t extents_from_size(struct cmd_context *cmd, uint64_t size, int pool_is_active(const struct logical_volume *pool_lv); int update_pool_lv(struct logical_volume *lv, int activate); +int update_pool_params(struct cmd_context *cmd, unsigned attr, int passed_args, + uint32_t data_extents, uint32_t extent_size, + uint32_t *chunk_size, thin_discards_t *discards, + uint64_t *pool_metadata_size); int get_pool_discards(const char *str, thin_discards_t *discards); const char *get_pool_discards_name(thin_discards_t discards); diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c index c994a2e8c..10c8f43ab 100644 --- a/lib/metadata/thin_manip.c +++ b/lib/metadata/thin_manip.c @@ -20,6 +20,7 @@ #include "lv_alloc.h" #include "archiver.h" #include "defaults.h" +#include "display.h" int attach_pool_metadata_lv(struct lv_segment *pool_seg, struct logical_volume *metadata_lv) { @@ -523,6 +524,93 @@ int update_pool_lv(struct logical_volume *lv, int activate) return 1; } +int update_pool_params(struct cmd_context *cmd, unsigned attr, int passed_args, + uint32_t data_extents, uint32_t extent_size, + uint32_t *chunk_size, thin_discards_t *discards, + uint64_t *pool_metadata_size) +{ + size_t estimate_chunk_size; + + if (!(attr & THIN_FEATURE_BLOCK_SIZE) && + (*chunk_size & (*chunk_size - 1))) { + log_error("Chunk size must be a power of 2 for this thin target version."); + return 0; + } else if (*chunk_size & (DM_THIN_MIN_DATA_BLOCK_SIZE - 1)) { + log_error("Chunk size must be multiple of %s.", + display_size(cmd, DM_THIN_MIN_DATA_BLOCK_SIZE)); + return 0; + } + + if (!*pool_metadata_size) { + /* Defaults to nr_pool_blocks * 64b converted to size in sectors */ + *pool_metadata_size = (uint64_t) data_extents * extent_size / + (*chunk_size * (SECTOR_SIZE / UINT64_C(64))); + /* Check if we could eventually use bigger chunk size */ + if (!(passed_args & PASS_ARG_CHUNK_SIZE)) { + while ((*pool_metadata_size > + (DEFAULT_THIN_POOL_OPTIMAL_SIZE / SECTOR_SIZE)) && + (*chunk_size < DM_THIN_MAX_DATA_BLOCK_SIZE)) { + *chunk_size <<= 1; + *pool_metadata_size >>= 1; + } + log_verbose("Setting chunk size to %s.", + display_size(cmd, *chunk_size)); + } else if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { + /* Suggest bigger chunk size */ + estimate_chunk_size = (uint64_t) data_extents * extent_size / + (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE * + (SECTOR_SIZE / UINT64_C(64))); + log_warn("WARNING: Chunk size is too small for pool, suggested minimum is %s.", + display_size(cmd, UINT64_C(1) << (ffs(estimate_chunk_size) + 1))); + } + + /* Round up to extent size */ + if (*pool_metadata_size % extent_size) + *pool_metadata_size += extent_size - *pool_metadata_size % extent_size; + } else { + estimate_chunk_size = (uint64_t) data_extents * extent_size / + (*pool_metadata_size * (SECTOR_SIZE / UINT64_C(64))); + /* Check to eventually use bigger chunk size */ + if (!(passed_args & PASS_ARG_CHUNK_SIZE)) { + *chunk_size = estimate_chunk_size; + + if (*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) + *chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE; + else if (*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE) + *chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE; + + log_verbose("Setting chunk size %s.", + display_size(cmd, *chunk_size)); + } else if (*chunk_size < estimate_chunk_size) { + /* Suggest bigger chunk size */ + log_warn("WARNING: Chunk size is smaller then suggested minimum size %s.", + display_size(cmd, estimate_chunk_size)); + } + } + + if ((uint64_t) *chunk_size > (uint64_t) data_extents * extent_size) { + log_error("Chunk size is bigger then pool data size."); + return 0; + } + + if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { + if (passed_args & PASS_ARG_POOL_METADATA_SIZE) + log_warn("WARNING: Maximum supported pool metadata size is %s.", + display_size(cmd, 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)); + *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; + } else if (*pool_metadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) { + if (passed_args & PASS_ARG_POOL_METADATA_SIZE) + log_warn("WARNING: Minimum supported pool metadata size is %s.", + display_size(cmd, 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)); + *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE; + } + + log_verbose("Setting pool metadata size to %s.", + display_size(cmd, *pool_metadata_size)); + + return 1; +} + int get_pool_discards(const char *str, thin_discards_t *discards) { if (!strcasecmp(str, "passdown")) |