diff --git a/inc/ocf_err.h b/inc/ocf_err.h index d7fdbb6..a6116b4 100644 --- a/inc/ocf_err.h +++ b/inc/ocf_err.h @@ -149,7 +149,10 @@ typedef enum { /** Failed to remove the core */ OCF_ERR_CORE_NOT_REMOVED, - OCF_ERR_MAX = OCF_ERR_CORE_NOT_REMOVED, + /** Operation only allowed in standby mode **/ + OCF_ERR_CACHE_NOT_STANDBY, + + OCF_ERR_MAX = OCF_ERR_CACHE_NOT_STANDBY, } ocf_error_t; diff --git a/src/cleaning/cleaning.c b/src/cleaning/cleaning.c index 20d6cab..18587f1 100644 --- a/src/cleaning/cleaning.c +++ b/src/cleaning/cleaning.c @@ -97,6 +97,11 @@ void ocf_cleaner_run(ocf_cleaner_t cleaner, ocf_queue_t queue) return; } + if (ocf_cache_is_standby(cache)) { + cleaner->end(cleaner, SLEEP_TIME_MS); + return; + } + /* Sleep in case there is management operation in progress. */ if (ocf_mngt_cache_trylock(cache)) { cleaner->end(cleaner, SLEEP_TIME_MS); diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index 10ee7be..f1773b3 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -2963,6 +2963,9 @@ void ocf_mngt_cache_attach(ocf_cache_t cache, OCF_CHECK_NULL(cache); OCF_CHECK_NULL(cfg); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_STANDBY); + if (!cache->mngt_queue) OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL); @@ -3070,6 +3073,9 @@ void ocf_mngt_cache_load(ocf_cache_t cache, OCF_CHECK_NULL(cache); OCF_CHECK_NULL(cfg); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_STANDBY); + if (!cache->mngt_queue) OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL); @@ -3322,6 +3328,9 @@ void ocf_mngt_cache_save(ocf_cache_t cache, OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_STANDBY); + if (!cache->mngt_queue) OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL); @@ -3706,6 +3715,9 @@ void ocf_mngt_cache_detach(ocf_cache_t cache, OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_STANDBY); + if (!cache->mngt_queue) OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL); diff --git a/src/mngt/ocf_mngt_core.c b/src/mngt/ocf_mngt_core.c index 9070390..4490bc9 100644 --- a/src/mngt/ocf_mngt_core.c +++ b/src/mngt/ocf_mngt_core.c @@ -559,6 +559,9 @@ void ocf_mngt_cache_add_core(ocf_cache_t cache, OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(cache, NULL, priv, -OCF_ERR_CACHE_STANDBY); + if (!cache->mngt_queue) OCF_CMPL_RET(cache, NULL, priv, -OCF_ERR_INVAL); @@ -735,6 +738,9 @@ void ocf_mngt_cache_remove_core(ocf_core_t core, cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(cache, -OCF_ERR_CACHE_STANDBY); + if (!cache->mngt_queue) OCF_CMPL_RET(cache, -OCF_ERR_INVAL); @@ -852,6 +858,9 @@ void ocf_mngt_cache_detach_core(ocf_core_t core, cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(cache, -OCF_ERR_CACHE_STANDBY); + if (!cache->mngt_queue) OCF_CMPL_RET(cache, -OCF_ERR_INVAL); @@ -877,11 +886,17 @@ int ocf_mngt_core_set_uuid(ocf_core_t core, const struct ocf_volume_uuid *uuid) struct ocf_volume_uuid *current_uuid; int result; int diff; + ocf_cache_t cache; OCF_CHECK_NULL(core); OCF_CHECK_NULL(uuid); OCF_CHECK_NULL(uuid->data); + cache = ocf_core_get_cache(core); + + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + current_uuid = &ocf_core_get_volume(core)->uuid; result = env_memcmp(current_uuid->data, current_uuid->size, @@ -905,9 +920,16 @@ int ocf_mngt_core_set_uuid(ocf_core_t core, const struct ocf_volume_uuid *uuid) int ocf_mngt_core_set_user_metadata(ocf_core_t core, void *data, size_t size) { + ocf_cache_t cache; + OCF_CHECK_NULL(core); OCF_CHECK_NULL(data); + cache = ocf_core_get_cache(core); + + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + if (size > OCF_CORE_USER_DATA_SIZE) return -EINVAL; @@ -917,9 +939,16 @@ int ocf_mngt_core_set_user_metadata(ocf_core_t core, void *data, size_t size) int ocf_mngt_core_get_user_metadata(ocf_core_t core, void *data, size_t size) { + ocf_cache_t cache; + OCF_CHECK_NULL(core); OCF_CHECK_NULL(data); + cache = ocf_core_get_cache(core); + + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + if (size > sizeof(core->conf_meta->user_data)) return -EINVAL; @@ -957,8 +986,14 @@ static int _cache_mngt_set_core_seq_cutoff_threshold(ocf_core_t core, void *cntx int ocf_mngt_core_set_seq_cutoff_threshold(ocf_core_t core, uint32_t thresh) { + ocf_cache_t cache; + OCF_CHECK_NULL(core); + cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + return _cache_mngt_set_core_seq_cutoff_threshold(core, &thresh); } @@ -976,9 +1011,15 @@ int ocf_mngt_core_set_seq_cutoff_threshold_all(ocf_cache_t cache, int ocf_mngt_core_get_seq_cutoff_threshold(ocf_core_t core, uint32_t *thresh) { + ocf_cache_t cache; + OCF_CHECK_NULL(core); OCF_CHECK_NULL(thresh); + cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + *thresh = ocf_core_get_seq_cutoff_threshold(core); return 0; @@ -1030,14 +1071,21 @@ static int _cache_mngt_set_core_seq_cutoff_policy(ocf_core_t core, void *cntx) int ocf_mngt_core_set_seq_cutoff_policy(ocf_core_t core, ocf_seq_cutoff_policy policy) { + ocf_cache_t cache; + OCF_CHECK_NULL(core); + cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + return _cache_mngt_set_core_seq_cutoff_policy(core, &policy); } int ocf_mngt_core_set_seq_cutoff_policy_all(ocf_cache_t cache, ocf_seq_cutoff_policy policy) { OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) return -OCF_ERR_CACHE_STANDBY; @@ -1048,9 +1096,15 @@ int ocf_mngt_core_set_seq_cutoff_policy_all(ocf_cache_t cache, int ocf_mngt_core_get_seq_cutoff_policy(ocf_core_t core, ocf_seq_cutoff_policy *policy) { + ocf_cache_t cache; + OCF_CHECK_NULL(core); OCF_CHECK_NULL(policy); + cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + *policy = ocf_core_get_seq_cutoff_policy(core); return 0; @@ -1089,8 +1143,14 @@ static int _cache_mngt_set_core_seq_cutoff_promo_count(ocf_core_t core, int ocf_mngt_core_set_seq_cutoff_promotion_count(ocf_core_t core, uint32_t count) { + ocf_cache_t cache; + OCF_CHECK_NULL(core); + cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + return _cache_mngt_set_core_seq_cutoff_promo_count(core, &count); } @@ -1109,9 +1169,15 @@ int ocf_mngt_core_set_seq_cutoff_promotion_count_all(ocf_cache_t cache, int ocf_mngt_core_get_seq_cutoff_promotion_count(ocf_core_t core, uint32_t *count) { + ocf_cache_t cache; + OCF_CHECK_NULL(core); OCF_CHECK_NULL(count); + cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + *count = ocf_core_get_seq_cutoff_promotion_count(core); return 0; @@ -1143,8 +1209,14 @@ static int _cache_mngt_set_core_seq_cutoff_promote_on_threshold( int ocf_mngt_core_set_seq_cutoff_promote_on_threshold(ocf_core_t core, bool promote) { + ocf_cache_t cache; + OCF_CHECK_NULL(core); + cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + return _cache_mngt_set_core_seq_cutoff_promote_on_threshold(core, &promote); } @@ -1164,9 +1236,15 @@ int ocf_mngt_core_set_seq_cutoff_promote_on_threshold_all(ocf_cache_t cache, int ocf_mngt_core_get_seq_cutoff_promote_on_threshold(ocf_core_t core, bool *promote) { + ocf_cache_t cache; + OCF_CHECK_NULL(core); OCF_CHECK_NULL(promote); + cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + *promote = ocf_core_get_seq_cutoff_promote_on_threshold(core); return 0; diff --git a/src/mngt/ocf_mngt_flush.c b/src/mngt/ocf_mngt_flush.c index 440db41..a7d9460 100644 --- a/src/mngt/ocf_mngt_flush.c +++ b/src/mngt/ocf_mngt_flush.c @@ -110,6 +110,12 @@ static void _ocf_mngt_begin_flush(ocf_pipeline_t pipeline, void *priv, bool ocf_mngt_core_is_dirty(ocf_core_t core) { + ocf_cache_t cache; + + cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + return false; + return !!env_atomic_read(&core->runtime_meta->dirty_clines); } @@ -120,6 +126,9 @@ bool ocf_mngt_cache_is_dirty(ocf_cache_t cache) OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + return false; + for_each_core(cache, core, core_id) { if (ocf_mngt_core_is_dirty(core)) return true; @@ -655,6 +664,9 @@ void ocf_mngt_cache_flush(ocf_cache_t cache, OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_STANDBY); + if (ocf_cache_is_standby(cache)) { ocf_cache_log(cache, log_err, "Cannot flush cache - cache is standby\n"); OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_STANDBY); @@ -749,6 +761,9 @@ void ocf_mngt_core_flush(ocf_core_t core, cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(core, priv, -OCF_ERR_CACHE_STANDBY); + if (!ocf_cache_is_device_attached(cache)) { ocf_cache_log(cache, log_err, "Cannot flush core - " "cache device is detached\n"); @@ -820,6 +835,9 @@ void ocf_mngt_cache_purge(ocf_cache_t cache, OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_STANDBY); + if (!cache->mngt_queue) { ocf_cache_log(cache, log_err, "Cannot purge cache - no flush queue set\n"); @@ -871,6 +889,9 @@ void ocf_mngt_core_purge(ocf_core_t core, cache = ocf_core_get_cache(core); core_id = ocf_core_get_id(core); + if (ocf_cache_is_standby(cache)) + OCF_CMPL_RET(core, priv, -OCF_ERR_CACHE_STANDBY); + if (!cache->mngt_queue) { ocf_core_log(core, log_err, "Cannot purge core - no flush queue set\n"); @@ -902,6 +923,9 @@ void ocf_mngt_cache_flush_interrupt(ocf_cache_t cache) { OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + return; + ocf_cache_log(cache, log_alert, "Flushing interrupt\n"); cache->flushing_interrupted = 1; } diff --git a/src/ocf_cache.c b/src/ocf_cache.c index 67e29ad..f5c4470 100644 --- a/src/ocf_cache.c +++ b/src/ocf_cache.c @@ -358,6 +358,10 @@ static void ocf_cache_volume_submit_io(struct ocf_io *io) ocf_io_end(io, -OCF_ERR_IO); return; } + if (unlikely(!ocf_cache_is_standby(cache))) { + ocf_io_end(io, -OCF_ERR_CACHE_NOT_STANDBY); + return; + } env_atomic_set(&priv->remaining, 3); env_atomic_set(&priv->error, 0); @@ -402,6 +406,10 @@ static void ocf_cache_volume_submit_flush(struct ocf_io *io) ocf_io_end(io, -OCF_ERR_IO); return; } + if (unlikely(!ocf_cache_is_standby(cache))) { + ocf_io_end(io, -OCF_ERR_CACHE_NOT_STANDBY); + return; + } env_atomic_set(&priv->remaining, 1); @@ -430,6 +438,10 @@ static void ocf_cache_volume_submit_discard(struct ocf_io *io) ocf_io_end(io, -OCF_ERR_IO); return; } + if (unlikely(!ocf_cache_is_standby(cache))) { + ocf_io_end(io, -OCF_ERR_CACHE_NOT_STANDBY); + return; + } env_atomic_set(&priv->remaining, 1); diff --git a/src/ocf_core.c b/src/ocf_core.c index a1fcc54..d1668f8 100644 --- a/src/ocf_core.c +++ b/src/ocf_core.c @@ -134,6 +134,9 @@ int ocf_core_visit(ocf_cache_t cache, ocf_core_visitor_t visitor, void *cntx, OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + if (!visitor) return -OCF_ERR_INVAL; @@ -287,6 +290,11 @@ void ocf_core_volume_submit_io(struct ocf_io *io) return; } + if (unlikely(ocf_cache_is_standby(cache))) { + ocf_io_end(io, -OCF_ERR_CACHE_STANDBY); + return; + } + ret = ocf_req_alloc_map(req); if (ret) { ocf_io_end(io, ret); @@ -348,6 +356,11 @@ static void ocf_core_volume_submit_flush(struct ocf_io *io) return; } + if (unlikely(ocf_cache_is_standby(cache))) { + ocf_io_end(io, -OCF_ERR_CACHE_STANDBY); + return; + } + req->core = core; req->complete = ocf_req_complete; @@ -386,6 +399,11 @@ static void ocf_core_volume_submit_discard(struct ocf_io *io) return; } + if (unlikely(ocf_cache_is_standby(cache))) { + ocf_io_end(io, -OCF_ERR_CACHE_STANDBY); + return; + } + ret = ocf_req_alloc_map_discard(req); if (ret) { ocf_io_end(io, -OCF_ERR_NO_MEM); @@ -544,6 +562,9 @@ int ocf_core_get_info(ocf_core_t core, struct ocf_core_info *info) cache = ocf_core_get_cache(core); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + if (!info) return -OCF_ERR_INVAL; diff --git a/src/ocf_io_class.c b/src/ocf_io_class.c index b856e90..3f4dabd 100644 --- a/src/ocf_io_class.c +++ b/src/ocf_io_class.c @@ -17,6 +17,9 @@ int ocf_cache_io_class_get_info(ocf_cache_t cache, uint32_t io_class, OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + if (!info) return -OCF_ERR_INVAL; @@ -58,6 +61,9 @@ int ocf_io_class_visit(ocf_cache_t cache, ocf_io_class_visitor_t visitor, OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + if (!visitor) return -OCF_ERR_INVAL; diff --git a/src/ocf_metadata.c b/src/ocf_metadata.c index f43b61c..8531b3e 100644 --- a/src/ocf_metadata.c +++ b/src/ocf_metadata.c @@ -63,6 +63,9 @@ int ocf_metadata_check_invalid_before(ocf_cache_t cache, uint64_t addr) OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + line = ocf_atomic_addr2line(cache, addr); pos = ocf_atomic_addr2pos(cache, addr); @@ -86,6 +89,9 @@ int ocf_metadata_check_invalid_after(ocf_cache_t cache, uint64_t addr, OCF_CHECK_NULL(cache); + if (ocf_cache_is_standby(cache)) + return -OCF_ERR_CACHE_STANDBY; + line = ocf_atomic_addr2line(cache, addr + bytes); pos = ocf_atomic_addr2pos(cache, addr + bytes); diff --git a/tests/functional/pyocf/types/shared.py b/tests/functional/pyocf/types/shared.py index 5ec4fbf..793b563 100644 --- a/tests/functional/pyocf/types/shared.py +++ b/tests/functional/pyocf/types/shared.py @@ -57,6 +57,7 @@ class OcfErrorCode(IntEnum): OCF_ERR_CORE_SIZE_MISMATCH = auto() OCF_ERR_STANDBY_ATTACHED = auto() OCF_ERR_CORE_NOT_REMOVED = auto() + OCF_ERR_CACHE_NOT_STANDBY = auto() class OcfCompletion: diff --git a/tests/unit/tests/cleaning/cleaning.c/ocf_cleaner_run_test.c b/tests/unit/tests/cleaning/cleaning.c/ocf_cleaner_run_test.c index d5cab95..d2d0bce 100644 --- a/tests/unit/tests/cleaning/cleaning.c/ocf_cleaner_run_test.c +++ b/tests/unit/tests/cleaning/cleaning.c/ocf_cleaner_run_test.c @@ -91,6 +91,11 @@ void __wrap_ocf_mngt_cache_unlock(env_rwsem *s) function_called(); } +bool __wrap_ocf_cache_is_standby(ocf_cache_t cache) +{ + return false; +} + static void cleaner_complete(ocf_cleaner_t cleaner, uint32_t interval) { function_called();