From 92c7e125495e882b2a09505e00b1a2827ba1b998 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 22 Jul 2019 14:43:30 +0200 Subject: [PATCH] Remove core id from public API Signed-off-by: Robert Baldyga --- inc/ocf_mngt.h | 17 +- src/mngt/ocf_mngt_core.c | 519 +++++++++++++++++---------------------- src/ocf_cache_priv.h | 3 + 3 files changed, 236 insertions(+), 303 deletions(-) diff --git a/inc/ocf_mngt.h b/inc/ocf_mngt.h index 57d282e..65e9d4c 100644 --- a/inc/ocf_mngt.h +++ b/inc/ocf_mngt.h @@ -19,6 +19,11 @@ * @brief Core start configuration */ struct ocf_mngt_core_config { + /** + * @brief OCF core name + */ + const char *name; + /** * @brief OCF core volume UUID */ @@ -29,17 +34,6 @@ struct ocf_mngt_core_config { */ uint8_t volume_type; - /** - * @brief OCF core ID number - */ - ocf_core_id_t core_id; - - /** - * @brief OCF core name. In case of being NULL, core id is stringified - * to core name - */ - const char *name; - /** * @brief Add core to pool if cache isn't present or add core to * earlier loaded cache @@ -66,7 +60,6 @@ struct ocf_mngt_core_config { static inline void ocf_mngt_core_config_set_default( struct ocf_mngt_core_config *cfg) { - cfg->core_id = OCF_CORE_ID_INVALID; cfg->try_add = false; cfg->seq_cutoff_threshold = 1024; cfg->user_metadata.data = NULL; diff --git a/src/mngt/ocf_mngt_core.c b/src/mngt/ocf_mngt_core.c index 85eef77..c1a7e1c 100644 --- a/src/mngt/ocf_mngt_core.c +++ b/src/mngt/ocf_mngt_core.c @@ -79,47 +79,6 @@ void ocf_mngt_core_clear_uuid_metadata(ocf_core_t core) ocf_mngt_core_set_uuid_metadata(core, &uuid, NULL); } - -static int _ocf_mngt_cache_try_add_core(ocf_cache_t cache, ocf_core_t *core, - struct ocf_mngt_core_config *cfg) -{ - int result = 0; - ocf_core_t tmp_core; - ocf_volume_t volume; - - tmp_core = &cache->core[cfg->core_id]; - volume = &tmp_core->volume; - - if (ocf_ctx_get_volume_type_id(cache->owner, volume->type) != - cfg->volume_type) { - result = -OCF_ERR_INVAL_VOLUME_TYPE; - goto error_out; - } - - result = ocf_volume_open(volume, NULL); - if (result) - goto error_out; - - if (!ocf_volume_get_length(volume)) { - result = -OCF_ERR_CORE_NOT_AVAIL; - goto error_after_open; - } - - tmp_core->opened = true; - - if (!(--cache->ocf_core_inactive_count)) - env_bit_clear(ocf_cache_state_incomplete, &cache->cache_state); - - *core = tmp_core; - return 0; - -error_after_open: - ocf_volume_close(volume); -error_out: - *core = NULL; - return result; -} - struct ocf_cache_add_core_context { ocf_mngt_cache_add_core_end_t cmpl; void *priv; @@ -140,20 +99,21 @@ struct ocf_cache_add_core_context { static void _ocf_mngt_cache_add_core_handle_error( struct ocf_cache_add_core_context *context) { - struct ocf_mngt_core_config *cfg = &context->cfg; ocf_cache_t cache = context->cache; ocf_core_t core = context->core; + ocf_core_id_t core_id; ocf_volume_t volume; ocf_cleaning_t clean_type; if (!core) return; + core_id = ocf_core_get_id(core); volume = &core->volume; clean_type = cache->conf_meta->cleaning_policy_type; if (context->flags.counters_allocated) { - env_bit_clear(cfg->core_id, + env_bit_clear(core_id, cache->conf_meta->valid_core_bitmap); core->conf_meta->added = false; core->opened = false; @@ -165,7 +125,7 @@ static void _ocf_mngt_cache_add_core_handle_error( if (context->flags.clean_pol_added) { if (cleaning_policy_ops[clean_type].remove_core) cleaning_policy_ops[clean_type].remove_core(cache, - cfg->core_id); + core_id); } if (context->flags.volume_opened) @@ -178,123 +138,6 @@ static void _ocf_mngt_cache_add_core_handle_error( ocf_mngt_core_clear_uuid_metadata(core); } -static void _ocf_mngt_cache_add_core_flush_sb_complete(void *priv, int error) -{ - struct ocf_cache_add_core_context *context = priv; - - if (error) - OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_WRITE_CACHE); - - /* Increase value of added cores */ - context->cache->conf_meta->core_count++; - - ocf_pipeline_next(context->pipeline); -} - -static void _ocf_mngt_cache_add_core(ocf_cache_t cache, - struct ocf_cache_add_core_context *context) -{ - struct ocf_mngt_core_config *cfg = &context->cfg; - ocf_core_t core; - struct ocf_volume_uuid new_uuid; - ocf_volume_t volume; - ocf_volume_type_t type; - ocf_seq_no_t core_sequence_no; - ocf_cleaning_t clean_type; - uint64_t length; - int result = 0; - - core = ocf_cache_get_core(cache, cfg->core_id); - context->core = core; - - volume = &core->volume; - volume->cache = cache; - - /* Set uuid */ - result = ocf_mngt_core_set_uuid_metadata(core, &cfg->uuid, &new_uuid); - if (result) - OCF_PL_FINISH_RET(context->pipeline, result); - - context->flags.uuid_set = true; - - type = ocf_ctx_get_volume_type(cache->owner, cfg->volume_type); - if (!type) { - OCF_PL_FINISH_RET(context->pipeline, - -OCF_ERR_INVAL_VOLUME_TYPE); - } - - result = ocf_volume_init(volume, type, &new_uuid, false); - if (result) - OCF_PL_FINISH_RET(context->pipeline, result); - - context->flags.volume_inited = true; - - if (cfg->user_metadata.data && cfg->user_metadata.size > 0) { - result = ocf_mngt_core_set_user_metadata(core, - cfg->user_metadata.data, - cfg->user_metadata.size); - if (result) - OCF_PL_FINISH_RET(context->pipeline, result); - } - - result = ocf_volume_open(volume, NULL); - if (result) - OCF_PL_FINISH_RET(context->pipeline, result); - - context->flags.volume_opened = true; - - length = ocf_volume_get_length(volume); - if (!length) - OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_CORE_NOT_AVAIL); - - core->conf_meta->length = length; - - clean_type = cache->conf_meta->cleaning_policy_type; - if (ocf_cache_is_device_attached(cache) && - cleaning_policy_ops[clean_type].add_core) { - result = cleaning_policy_ops[clean_type].add_core(cache, - cfg->core_id); - if (result) - OCF_PL_FINISH_RET(context->pipeline, result); - - context->flags.clean_pol_added = true; - } - - /* When adding new core to cache, allocate stat counters */ - core->counters = - env_zalloc(sizeof(*core->counters), ENV_MEM_NORMAL); - if (!core->counters) - OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_NO_MEM); - - context->flags.counters_allocated = true; - - /* When adding new core to cache, reset all core/cache statistics */ - ocf_core_stats_initialize(core); - env_atomic_set(&core->runtime_meta->cached_clines, 0); - env_atomic_set(&core->runtime_meta->dirty_clines, 0); - env_atomic64_set(&core->runtime_meta->dirty_since, 0); - - /* In metadata mark data this core was added into cache */ - env_bit_set(cfg->core_id, cache->conf_meta->valid_core_bitmap); - core->conf_meta->added = true; - core->opened = true; - - /* Set default cache parameters for sequential */ - core->conf_meta->seq_cutoff_policy = ocf_seq_cutoff_policy_default; - core->conf_meta->seq_cutoff_threshold = cfg->seq_cutoff_threshold; - - /* Add core sequence number for atomic metadata matching */ - core_sequence_no = _ocf_mngt_get_core_seq_no(cache); - if (core_sequence_no == OCF_SEQ_NO_INVALID) - OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_TOO_MANY_CORES); - - core->conf_meta->seq_no = core_sequence_no; - - /* Update super-block with core device addition */ - ocf_metadata_flush_superblock(cache, - _ocf_mngt_cache_add_core_flush_sb_complete, context); -} - static unsigned long _ffz(unsigned long word) { int i; @@ -330,118 +173,21 @@ static unsigned long _ocf_mngt_find_first_free_core(const unsigned long *bitmap) return ret; } -static int __ocf_mngt_lookup_core_uuid(ocf_cache_t cache, - struct ocf_mngt_core_config *cfg) +static int ocf_mngt_find_free_core(ocf_cache_t cache, ocf_core_t *core) { - int i; + ocf_core_id_t core_id; + ocf_core_t tmp_core; - for (i = 0; i < OCF_CORE_MAX; i++) { - ocf_core_t core = &cache->core[i]; + core_id = _ocf_mngt_find_first_free_core( + cache->conf_meta->valid_core_bitmap); - if (!env_bit_test(i, cache->conf_meta->valid_core_bitmap)) - continue; - - if (cache->core[i].opened) - continue; - - if (ocf_ctx_get_volume_type_id(cache->owner, core->volume.type) - != cfg->volume_type) { - continue; - } - - if (!env_strncmp(core->volume.uuid.data, cfg->uuid.data, - OCF_MIN(core->volume.uuid.size, - cfg->uuid.size))) { - return i; - } - } - - return OCF_CORE_MAX; -} - -static int __ocf_mngt_try_find_core_id(ocf_cache_t cache, - struct ocf_mngt_core_config *cfg, ocf_core_id_t tmp_core_id) -{ - if (tmp_core_id == OCF_CORE_MAX) { - ocf_cache_log(cache, log_err, "Core with given uuid not found " - "in cache metadata\n"); - return -OCF_ERR_CORE_NOT_AVAIL; - } - - if (cfg->core_id == OCF_CORE_MAX) { - cfg->core_id = tmp_core_id; - return 0; - } - - if (cfg->core_id != tmp_core_id) { - ocf_cache_log(cache, log_err, - "Given core id doesn't match with metadata\n"); - return -OCF_ERR_CORE_NOT_AVAIL; - } - - - cfg->core_id = tmp_core_id; - return 0; -} - -static int __ocf_mngt_find_core_id(ocf_cache_t cache, - struct ocf_mngt_core_config *cfg, ocf_core_id_t tmp_core_id) -{ - if (tmp_core_id != OCF_CORE_MAX) { - ocf_cache_log(cache, log_err, - "Core ID already added as inactive with id:" - " %hu.\n", tmp_core_id); - return -OCF_ERR_CORE_NOT_AVAIL; - } - - if (cfg->core_id == OCF_CORE_MAX) { - ocf_cache_log(cache, log_debug, "Core ID is unspecified - " - "will set first available number\n"); - - /* Core is unspecified */ - cfg->core_id = _ocf_mngt_find_first_free_core( - cache->conf_meta->valid_core_bitmap); - /* no need to check if find_first_zero_bit failed and - * *core_id == MAX_CORE_OBJS_PER_CACHE, as above there is check - * for core_count being greater or equal to - * MAX_CORE_OBJS_PER_CACHE - */ - } else if (cfg->core_id < OCF_CORE_MAX) { - /* check if id is not used already */ - if (env_bit_test(cfg->core_id, - cache->conf_meta->valid_core_bitmap)) { - ocf_cache_log(cache, log_debug, - "Core ID already allocated: %d.\n", - cfg->core_id); - return -OCF_ERR_CORE_NOT_AVAIL; - } - } else { - ocf_cache_log(cache, log_err, - "Core ID exceeds maximum of %d.\n", - OCF_CORE_MAX); - return -OCF_ERR_CORE_NOT_AVAIL; - } - - return 0; -} - -static int _ocf_mngt_find_core_id(ocf_cache_t cache, - struct ocf_mngt_core_config *cfg) -{ - int result; - ocf_core_id_t tmp_core_id; - - if (cache->conf_meta->core_count >= OCF_CORE_MAX) + tmp_core = ocf_cache_get_core(cache, core_id); + if (!tmp_core) return -OCF_ERR_TOO_MANY_CORES; - tmp_core_id = __ocf_mngt_lookup_core_uuid(cache, cfg); + *core = tmp_core; - if (cfg->try_add) - result = __ocf_mngt_try_find_core_id(cache, cfg, tmp_core_id); - else - result = __ocf_mngt_find_core_id(cache, cfg, tmp_core_id); - - return result; + return 0; } int ocf_mngt_core_init_front_volume(ocf_core_t core) @@ -469,30 +215,117 @@ int ocf_mngt_core_init_front_volume(ocf_core_t core) return ret; } -static void ocf_mngt_cache_add_core_prepare(ocf_pipeline_t pipeline, +static void ocf_mngt_cache_try_add_core_prepare(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) +{ + struct ocf_cache_add_core_context *context = priv; + struct ocf_mngt_core_config *cfg = &context->cfg; + ocf_cache_t cache = context->cache; + ocf_core_t core; + ocf_volume_t volume; + ocf_volume_type_t type; + ocf_ctx_t ctx = cache->owner; + int result; + + result = ocf_core_get_by_name(cache, cfg->name, &core); + if (result) + goto err; + + if (core->opened) { + result = -OCF_ERR_INVAL; + goto err; + } + + volume = ocf_core_get_volume(core); + type = ocf_volume_get_type(volume); + + if (ocf_ctx_get_volume_type_id(ctx, type) != cfg->volume_type) { + result = -OCF_ERR_INVAL_VOLUME_TYPE; + goto err; + } + + if (env_strncmp(volume->uuid.data, cfg->uuid.data, + OCF_MIN(volume->uuid.size, cfg->uuid.size))) { + result = -OCF_ERR_INVAL; + goto err; + } + + context->core = core; + + OCF_PL_NEXT_RET(pipeline); + +err: + ocf_cache_log(cache, log_err, "Core with given uuid not found " + "in cache metadata\n"); + OCF_PL_FINISH_RET(pipeline, result); +} + +static void ocf_mngt_cache_try_add_core_insert(ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_add_core_context *context = priv; ocf_cache_t cache = context->cache; + ocf_core_t core = context->core; + ocf_volume_t volume; + int result; + + ocf_core_log(core, log_debug, "Inserting core\n"); + + volume = ocf_core_get_volume(core); + + result = ocf_volume_open(volume, NULL); + if (result) + OCF_PL_FINISH_RET(pipeline, result); + + if (!ocf_volume_get_length(volume)) { + result = -OCF_ERR_CORE_NOT_AVAIL; + goto error_after_open; + } + + core->opened = true; + + if (!(--cache->ocf_core_inactive_count)) + env_bit_clear(ocf_cache_state_incomplete, &cache->cache_state); + + OCF_PL_NEXT_RET(pipeline); + +error_after_open: + ocf_volume_close(volume); + OCF_PL_FINISH_RET(pipeline, result); +} + +static void ocf_mngt_cache_add_core_prepare(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) +{ + struct ocf_cache_add_core_context *context = priv; + struct ocf_mngt_core_config *cfg = &context->cfg; + ocf_cache_t cache = context->cache; ocf_core_t core; int result; - result = _ocf_mngt_find_core_id(cache, &context->cfg); - if (result) - OCF_PL_FINISH_RET(context->pipeline, result); - - if (!context->cfg.name) - OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_INVAL); - - result = ocf_core_get_by_name(cache, context->cfg.name, &core); - if (!result && !context->cfg.try_add) + result = ocf_core_get_by_name(cache, cfg->name, &core); + if (!result) OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_CORE_EXIST); - result = ocf_mngt_core_set_name(&cache->core[context->cfg.core_id], - context->cfg.name); + result = ocf_mngt_find_free_core(cache, &core); if (result) OCF_PL_FINISH_RET(context->pipeline, result); + context->core = core; + + ocf_pipeline_next(context->pipeline); +} + +static void _ocf_mngt_cache_add_core_flush_sb_complete(void *priv, int error) +{ + struct ocf_cache_add_core_context *context = priv; + + if (error) + OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_WRITE_CACHE); + + /* Increase value of added cores */ + context->cache->conf_meta->core_count++; + ocf_pipeline_next(context->pipeline); } @@ -500,20 +333,109 @@ static void ocf_mngt_cache_add_core_insert(ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_add_core_context *context = priv; + struct ocf_mngt_core_config *cfg = &context->cfg; ocf_cache_t cache = context->cache; - const char *core_name = context->cfg.name; - int result; + ocf_core_t core = context->core; + ocf_core_id_t core_id; + struct ocf_volume_uuid new_uuid; + ocf_volume_t volume; + ocf_volume_type_t type; + ocf_seq_no_t core_sequence_no; + ocf_cleaning_t clean_type; + uint64_t length; + int result = 0; - ocf_cache_log(cache, log_debug, "Inserting core %s\n", core_name); + ocf_cache_log(cache, log_debug, "Inserting core %s\n", cfg->name); - if (context->cfg.try_add) { - result = _ocf_mngt_cache_try_add_core(cache, &context->core, - &context->cfg); + volume = ocf_core_get_volume(core); + volume->cache = cache; + core_id = ocf_core_get_id(core); - OCF_PL_NEXT_ON_SUCCESS_RET(context->pipeline, result); + result = ocf_mngt_core_set_name(core, cfg->name); + if (result) + OCF_PL_FINISH_RET(pipeline, result); + + /* Set uuid */ + result = ocf_mngt_core_set_uuid_metadata(core, &cfg->uuid, &new_uuid); + if (result) + OCF_PL_FINISH_RET(pipeline, result); + + context->flags.uuid_set = true; + + type = ocf_ctx_get_volume_type(cache->owner, cfg->volume_type); + if (!type) + OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL_VOLUME_TYPE); + + result = ocf_volume_init(volume, type, &new_uuid, false); + if (result) + OCF_PL_FINISH_RET(pipeline, result); + + context->flags.volume_inited = true; + + if (cfg->user_metadata.data && cfg->user_metadata.size > 0) { + result = ocf_mngt_core_set_user_metadata(core, + cfg->user_metadata.data, + cfg->user_metadata.size); + if (result) + OCF_PL_FINISH_RET(pipeline, result); } - _ocf_mngt_cache_add_core(cache, context); + result = ocf_volume_open(volume, NULL); + if (result) + OCF_PL_FINISH_RET(pipeline, result); + + context->flags.volume_opened = true; + + length = ocf_volume_get_length(volume); + if (!length) + OCF_PL_FINISH_RET(pipeline, -OCF_ERR_CORE_NOT_AVAIL); + + core->conf_meta->length = length; + + clean_type = cache->conf_meta->cleaning_policy_type; + if (ocf_cache_is_device_attached(cache) && + cleaning_policy_ops[clean_type].add_core) { + result = cleaning_policy_ops[clean_type].add_core(cache, + core_id); + if (result) + OCF_PL_FINISH_RET(pipeline, result); + + context->flags.clean_pol_added = true; + } + + /* When adding new core to cache, allocate stat counters */ + core->counters = + env_zalloc(sizeof(*core->counters), ENV_MEM_NORMAL); + if (!core->counters) + OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_NO_MEM); + + context->flags.counters_allocated = true; + + /* When adding new core to cache, reset all core/cache statistics */ + ocf_core_stats_initialize(core); + env_atomic_set(&core->runtime_meta->cached_clines, 0); + env_atomic_set(&core->runtime_meta->dirty_clines, 0); + env_atomic64_set(&core->runtime_meta->dirty_since, 0); + + /* In metadata mark data this core was added into cache */ + env_bit_set(core_id, cache->conf_meta->valid_core_bitmap); + core->conf_meta->added = true; + core->opened = true; + + /* Set default cache parameters for sequential */ + core->conf_meta->seq_cutoff_policy = ocf_seq_cutoff_policy_default; + core->conf_meta->seq_cutoff_threshold = cfg->seq_cutoff_threshold; + + /* Add core sequence number for atomic metadata matching */ + core_sequence_no = _ocf_mngt_get_core_seq_no(cache); + if (core_sequence_no == OCF_SEQ_NO_INVALID) + OCF_PL_FINISH_RET(pipeline, -OCF_ERR_TOO_MANY_CORES); + + core->conf_meta->seq_no = core_sequence_no; + + /* Update super-block with core device addition */ + ocf_metadata_flush_superblock(cache, + _ocf_mngt_cache_add_core_flush_sb_complete, context); } static void ocf_mngt_cache_add_core_init_front_volume(ocf_pipeline_t pipeline, @@ -557,7 +479,18 @@ out: ocf_pipeline_destroy(context->pipeline); } -struct ocf_pipeline_properties ocf_mngt_cache_add_core_pipeline_properties = { +struct ocf_pipeline_properties ocf_mngt_cache_try_add_core_pipeline_props = { + .priv_size = sizeof(struct ocf_cache_add_core_context), + .finish = ocf_mngt_cache_add_core_finish, + .steps = { + OCF_PL_STEP(ocf_mngt_cache_try_add_core_prepare), + OCF_PL_STEP(ocf_mngt_cache_try_add_core_insert), + OCF_PL_STEP(ocf_mngt_cache_add_core_init_front_volume), + OCF_PL_STEP_TERMINATOR(), + }, +}; + +struct ocf_pipeline_properties ocf_mngt_cache_add_core_pipeline_props = { .priv_size = sizeof(struct ocf_cache_add_core_context), .finish = ocf_mngt_cache_add_core_finish, .steps = { @@ -583,8 +516,12 @@ void ocf_mngt_cache_add_core(ocf_cache_t cache, if (!cache->mngt_queue) OCF_CMPL_RET(cache, NULL, priv, -OCF_ERR_INVAL); - result = ocf_pipeline_create(&pipeline, cache, - &ocf_mngt_cache_add_core_pipeline_properties); + if (!cfg->name) + OCF_CMPL_RET(cache, NULL, priv, -OCF_ERR_INVAL); + + result = ocf_pipeline_create(&pipeline, cache, cfg->try_add ? + &ocf_mngt_cache_try_add_core_pipeline_props : + &ocf_mngt_cache_add_core_pipeline_props); if (result) OCF_CMPL_RET(cache, NULL, priv, -OCF_ERR_NO_MEM); @@ -866,7 +803,7 @@ void ocf_mngt_cache_detach_core(ocf_core_t core, context->cmpl = cmpl; context->priv = priv; context->pipeline = pipeline; - context->cache = ocf_core_get_cache(core); + context->cache = cache; context->core = core; context->core_name = ocf_core_get_name(core); diff --git a/src/ocf_cache_priv.h b/src/ocf_cache_priv.h index 113751c..033102f 100644 --- a/src/ocf_cache_priv.h +++ b/src/ocf_cache_priv.h @@ -172,6 +172,9 @@ struct ocf_cache { static inline ocf_core_t ocf_cache_get_core(ocf_cache_t cache, ocf_core_id_t core_id) { + if (core_id >= OCF_CORE_MAX) + return NULL; + return &cache->core[core_id]; }