diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index 537f8e0..4300031 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -1024,6 +1024,23 @@ void ocf_metadata_flush_all(ocf_cache_t cache, ocf_pipeline_next(pipeline); } +/* + * Flush collision metadata + */ +void ocf_metadata_flush_collision(ocf_cache_t cache, + ocf_metadata_end_t cmpl, void *priv) +{ + struct ocf_metadata_ctrl *ctrl; + struct ocf_metadata_raw *raw; + + OCF_DEBUG_TRACE(cache); + + ctrl = cache->metadata.priv; + raw = &ctrl->raw_desc[metadata_segment_collision]; + + ocf_metadata_raw_flush_all(cache, raw, cmpl, priv); +} + /* * Flush specified cache line */ diff --git a/src/metadata/metadata.h b/src/metadata/metadata.h index 5507b08..a72a927 100644 --- a/src/metadata/metadata.h +++ b/src/metadata/metadata.h @@ -123,6 +123,16 @@ ocf_cache_line_t ocf_metadata_get_pages_count(struct ocf_cache *cache); void ocf_metadata_flush_all(ocf_cache_t cache, ocf_metadata_end_t cmpl, void *priv); +/** + * @brief Flush metadata collision segment + * + * @param cache - Cache instance + * @param cmpl - Completion callback + * @param priv - Completion context + */ +void ocf_metadata_flush_collision(ocf_cache_t cache, + ocf_metadata_end_t cmpl, void *priv); + /** * @brief Mark specified cache line to be flushed * diff --git a/src/mngt/ocf_mngt_core.c b/src/mngt/ocf_mngt_core.c index 58b30cf..1dd5cb9 100644 --- a/src/mngt/ocf_mngt_core.c +++ b/src/mngt/ocf_mngt_core.c @@ -603,7 +603,7 @@ static void ocf_mngt_cache_remove_core_finish(ocf_pipeline_t pipeline, ocf_pipeline_destroy(context->pipeline); } -static void ocf_mngt_cache_remove_core_flush_sb_complete(void *priv, int error) +static void ocf_mngt_cache_remove_core_flush_meta_complete(void *priv, int error) { struct ocf_mngt_cache_remove_core_context *context = priv; @@ -611,6 +611,27 @@ static void ocf_mngt_cache_remove_core_flush_sb_complete(void *priv, int error) OCF_PL_NEXT_ON_SUCCESS_RET(context->pipeline, error); } +static void _ocf_mngt_cache_remove_core_attached(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) +{ + struct ocf_mngt_cache_remove_core_context *context = priv; + ocf_cache_t cache = context->cache; + ocf_core_t core = context->core; + + if (!ocf_cache_is_device_attached(cache)) + OCF_PL_NEXT_RET(pipeline); + + cache_mngt_core_deinit_attached_meta(core); + cache_mngt_core_remove_from_cleaning_pol(core); + + if (env_atomic_read(&core->runtime_meta->dirty_clines) == 0) + OCF_PL_NEXT_RET(pipeline); + + ocf_metadata_flush_collision(cache, + ocf_mngt_cache_remove_core_flush_meta_complete, + context); +} + static void _ocf_mngt_cache_remove_core(ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { @@ -620,18 +641,13 @@ static void _ocf_mngt_cache_remove_core(ocf_pipeline_t pipeline, void *priv, ocf_core_log(core, log_debug, "Removing core\n"); - /* Deinit everything*/ - if (ocf_cache_is_device_attached(cache)) { - cache_mngt_core_deinit_attached_meta(core); - cache_mngt_core_remove_from_cleaning_pol(core); - } cache_mngt_core_remove_from_meta(core); cache_mngt_core_remove_from_cache(core); cache_mngt_core_deinit(core); - /* Update super-block with core device removal */ ocf_metadata_flush_superblock(cache, - ocf_mngt_cache_remove_core_flush_sb_complete, context); + ocf_mngt_cache_remove_core_flush_meta_complete, + context); } static void ocf_mngt_cache_remove_core_wait_cleaning_complete(void *priv) @@ -660,6 +676,7 @@ struct ocf_pipeline_properties ocf_mngt_cache_remove_core_pipeline_props = { .finish = ocf_mngt_cache_remove_core_finish, .steps = { OCF_PL_STEP(ocf_mngt_cache_remove_core_wait_cleaning), + OCF_PL_STEP(_ocf_mngt_cache_remove_core_attached), OCF_PL_STEP(_ocf_mngt_cache_remove_core), OCF_PL_STEP_TERMINATOR(), },