From aa4622cc013bf09101cd3ff13b59e23293bfd441 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Fri, 25 Mar 2022 21:32:55 +0100 Subject: [PATCH] Make core remove error recoverable First try to clean only the mapping. This operation does not require any rollback, so even if flushing collision fails, core object is still intact. In case of error we inform user that core was not removed by returning new error code (-OCF_ERR_CORE_NOT_REMOVED). After flushing collision succeeds we remove core from metadata and flush superblock at the end. At that point the core is fully removed from OCF and even if superblock flush error occurs there is nothing we can do about it, so we just return the error code. Signed-off-by: Robert Baldyga --- inc/ocf_err.h | 5 ++++- src/mngt/ocf_mngt_core.c | 26 +++++++++++++++++++------- tests/functional/pyocf/types/shared.py | 1 + 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/inc/ocf_err.h b/inc/ocf_err.h index ec53393..d7fdbb6 100644 --- a/inc/ocf_err.h +++ b/inc/ocf_err.h @@ -146,7 +146,10 @@ typedef enum { /** Operation invalid with cache drive atatched in failover standby */ OCF_ERR_STANDBY_ATTACHED, - OCF_ERR_MAX = OCF_ERR_STANDBY_ATTACHED, + /** Failed to remove the core */ + OCF_ERR_CORE_NOT_REMOVED, + + OCF_ERR_MAX = OCF_ERR_CORE_NOT_REMOVED, } ocf_error_t; diff --git a/src/mngt/ocf_mngt_core.c b/src/mngt/ocf_mngt_core.c index db56cbe..9070390 100644 --- a/src/mngt/ocf_mngt_core.c +++ b/src/mngt/ocf_mngt_core.c @@ -632,15 +632,16 @@ 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_meta_complete(void *priv, int error) +static void ocf_mngt_cache_remove_core_flush_collision_complete(void *priv, + int error) { struct ocf_mngt_cache_remove_core_context *context = priv; - error = error ? -OCF_ERR_WRITE_CACHE : 0; + error = error ? -OCF_ERR_CORE_NOT_REMOVED : 0; OCF_PL_NEXT_ON_SUCCESS_RET(context->pipeline, error); } -static void _ocf_mngt_cache_remove_core_attached(ocf_pipeline_t pipeline, +static void _ocf_mngt_cache_remove_core_mapping(ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { struct ocf_mngt_cache_remove_core_context *context = priv; @@ -651,16 +652,24 @@ static void _ocf_mngt_cache_remove_core_attached(ocf_pipeline_t pipeline, 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, + ocf_mngt_cache_remove_core_flush_collision_complete, context); } +static void ocf_mngt_cache_remove_core_flush_superblock_complete(void *priv, + int error) +{ + struct ocf_mngt_cache_remove_core_context *context = priv; + + error = error ? -OCF_ERR_WRITE_CACHE : 0; + OCF_PL_NEXT_ON_SUCCESS_RET(context->pipeline, error); +} + static void _ocf_mngt_cache_remove_core(ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { @@ -670,12 +679,15 @@ static void _ocf_mngt_cache_remove_core(ocf_pipeline_t pipeline, void *priv, ocf_core_log(core, log_debug, "Removing core\n"); + if (ocf_cache_is_device_attached(cache)) + 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); ocf_metadata_flush_superblock(cache, - ocf_mngt_cache_remove_core_flush_meta_complete, + ocf_mngt_cache_remove_core_flush_superblock_complete, context); } @@ -705,7 +717,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_mapping), OCF_PL_STEP(_ocf_mngt_cache_remove_core), OCF_PL_STEP_TERMINATOR(), }, diff --git a/tests/functional/pyocf/types/shared.py b/tests/functional/pyocf/types/shared.py index f4e7c6c..5ec4fbf 100644 --- a/tests/functional/pyocf/types/shared.py +++ b/tests/functional/pyocf/types/shared.py @@ -56,6 +56,7 @@ class OcfErrorCode(IntEnum): OCF_ERR_CACHE_STANDBY = auto() OCF_ERR_CORE_SIZE_MISMATCH = auto() OCF_ERR_STANDBY_ATTACHED = auto() + OCF_ERR_CORE_NOT_REMOVED = auto() class OcfCompletion: