aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2013-03-11 12:37:09 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2013-03-13 15:13:54 +0100
commitb36a776a7fed84fa6228ffa287b4c9ccdf355ddf (patch)
treef27b14dca70a81f8298adda5c02d1318eb5b5842 /lib
parentf06dd8725a85d344820eda91835c58f489097563 (diff)
downloadlvm2-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.h4
-rw-r--r--lib/metadata/thin_manip.c88
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"))