#include "ocf/ocf.h"
#include "ocf_mngt_common.h"
+#include "ocf_mngt_core_priv.h"
#include "../ocf_priv.h"
#include "../ocf_ctx_priv.h"
#include "../metadata/metadata.h"
#include "../engine/cache_engine.h"
-#include "../utils/utils_req.h"
-#include "../utils/utils_device.h"
+#include "../ocf_request.h"
#include "../eviction/ops.h"
#include "../ocf_logger_priv.h"
#include "../ocf_queue_priv.h"
#include "../engine/engine_common.h"
/* Close if opened */
-int cache_mng_core_close(ocf_cache_t cache, ocf_core_id_t core_id)
+int cache_mngt_core_close(ocf_core_t core)
{
- if (!cache->core[core_id].opened)
+ if (!core->opened)
return -OCF_ERR_CORE_IN_INACTIVE_STATE;
- ocf_volume_close(&cache->core[core_id].volume);
- cache->core[core_id].opened = false;
+ ocf_volume_close(&core->front_volume);
+ ocf_volume_deinit(&core->front_volume);
+
+ ocf_volume_close(&core->volume);
+ ocf_volume_deinit(&core->volume);
+ core->opened = false;
return 0;
}
/* Remove core from cleaning policy */
-void cache_mng_core_remove_from_cleaning_pol(struct ocf_cache *cache,
- int core_id)
+void cache_mngt_core_remove_from_cleaning_pol(ocf_core_t core)
{
+ ocf_cache_t cache = ocf_core_get_cache(core);
+ ocf_core_id_t core_id = ocf_core_get_id(core);
ocf_cleaning_t clean_pol_type;
- OCF_METADATA_LOCK_WR();
+ ocf_metadata_start_exclusive_access(&cache->metadata.lock);
clean_pol_type = cache->conf_meta->cleaning_policy_type;
if (cache->core[core_id].opened) {
}
}
- OCF_METADATA_UNLOCK_WR();
+ ocf_metadata_end_exclusive_access(&cache->metadata.lock);
}
/* Deinitialize core metadata in attached metadata */
-void cache_mng_core_deinit_attached_meta(struct ocf_cache *cache, int core_id)
+void cache_mngt_core_deinit_attached_meta(ocf_core_t core)
{
int retry = 1;
uint64_t core_size = 0;
ocf_cleaning_t clean_pol_type;
- ocf_volume_t core;
-
- core = &cache->core[core_id].volume;
+ ocf_cache_t cache = ocf_core_get_cache(core);
+ ocf_core_id_t core_id = ocf_core_get_id(core);
- core_size = ocf_volume_get_length(core);
+ core_size = ocf_volume_get_length(&core->volume);
if (!core_size)
core_size = ~0ULL;
- OCF_METADATA_LOCK_WR();
+ ocf_metadata_start_exclusive_access(&cache->metadata.lock);
clean_pol_type = cache->conf_meta->cleaning_policy_type;
while (retry) {
}
if (retry) {
- OCF_METADATA_UNLOCK_WR();
+ ocf_metadata_end_exclusive_access(&cache->metadata.lock);
env_msleep(100);
- OCF_METADATA_LOCK_WR();
+ ocf_metadata_start_exclusive_access(
+ &cache->metadata.lock);
}
}
- OCF_METADATA_UNLOCK_WR();
+ ocf_metadata_end_exclusive_access(&cache->metadata.lock);
}
/* Mark core as removed in metadata */
-void cache_mng_core_remove_from_meta(struct ocf_cache *cache, int core_id)
+void cache_mngt_core_remove_from_meta(ocf_core_t core)
{
- OCF_METADATA_LOCK_WR();
+ ocf_cache_t cache = ocf_core_get_cache(core);
+
+ ocf_metadata_start_exclusive_access(&cache->metadata.lock);
/* In metadata mark data this core was removed from cache */
- cache->core_conf_meta[core_id].added = false;
+ core->conf_meta->valid = false;
/* Clear UUID of core */
- ocf_metadata_clear_core_uuid(&cache->core[core_id]);
- cache->core_conf_meta[core_id].seq_no = OCF_SEQ_NO_INVALID;
+ ocf_mngt_core_clear_uuid_metadata(core);
+ core->conf_meta->seq_no = OCF_SEQ_NO_INVALID;
- OCF_METADATA_UNLOCK_WR();
+ ocf_metadata_end_exclusive_access(&cache->metadata.lock);
}
/* Deinit in-memory structures related to this core */
-void cache_mng_core_remove_from_cache(struct ocf_cache *cache, int core_id)
+void cache_mngt_core_remove_from_cache(ocf_core_t core)
{
- env_free(cache->core[core_id].counters);
- cache->core[core_id].counters = NULL;
+ ocf_cache_t cache = ocf_core_get_cache(core);
+ ocf_core_id_t core_id = ocf_core_get_id(core);
+
+ env_free(core->counters);
+ core->counters = NULL;
+ core->added = false;
env_bit_clear(core_id, cache->conf_meta->valid_core_bitmap);
- if (!cache->core[core_id].opened &&
- --cache->ocf_core_inactive_count == 0) {
+ if (!core->opened && --cache->ocf_core_inactive_count == 0)
env_bit_clear(ocf_cache_state_incomplete, &cache->cache_state);
- }
cache->conf_meta->core_count--;
}
void ocf_mngt_cache_put(ocf_cache_t cache)
{
+ ocf_ctx_t ctx;
+
OCF_CHECK_NULL(cache);
- if (env_atomic_dec_return(&cache->ref_count) == 0) {
+ if (ocf_refcnt_dec(&cache->refcnt.cache) == 0) {
+ ctx = cache->owner;
ocf_metadata_deinit(cache);
env_vfree(cache);
+ ocf_ctx_put(ctx);
}
}
-int ocf_mngt_cache_get_by_id(ocf_ctx_t ocf_ctx, ocf_cache_id_t id, ocf_cache_t *cache)
+int ocf_mngt_cache_get_by_name(ocf_ctx_t ctx, const char *name, size_t name_len,
+ ocf_cache_t *cache)
{
- int error = 0;
struct ocf_cache *instance = NULL;
struct ocf_cache *iter = NULL;
- OCF_CHECK_NULL(ocf_ctx);
+ OCF_CHECK_NULL(ctx);
OCF_CHECK_NULL(cache);
- *cache = NULL;
-
- if ((id < OCF_CACHE_ID_MIN) || (id > OCF_CACHE_ID_MAX)) {
- /* Cache id out of range */
- return -OCF_ERR_INVAL;
- }
-
/* Lock caches list */
- env_mutex_lock(&ocf_ctx->lock);
+ env_rmutex_lock(&ctx->lock);
- list_for_each_entry(iter, &ocf_ctx->caches, list) {
- if (iter->cache_id == id) {
+ list_for_each_entry(iter, &ctx->caches, list) {
+ if (!env_strncmp(ocf_cache_get_name(iter), OCF_CACHE_NAME_SIZE,
+ name, name_len)) {
instance = iter;
break;
}
if (instance) {
/* if cache is either fully initialized or during recovery */
- if (instance->valid_ocf_cache_device_t) {
- /* Increase reference counter */
- env_atomic_inc(&instance->ref_count);
- } else {
+ if (!ocf_refcnt_inc(&instance->refcnt.cache)) {
/* Cache not initialized yet */
instance = NULL;
}
}
- env_mutex_unlock(&ocf_ctx->lock);
+ env_rmutex_unlock(&ctx->lock);
if (!instance)
+ return -OCF_ERR_CACHE_NOT_EXIST;
+
+ *cache = instance;
+
+ return 0;
+}
+
+typedef void (*ocf_lock_fn_t)(ocf_async_lock_waiter_t waiter);
+
+typedef int (*ocf_trylock_fn_t)(ocf_async_lock_t lock);
+
+typedef void (*ocf_unlock_fn_t)(ocf_async_lock_t lock);
+
+struct ocf_mngt_cache_lock_context {
+ ocf_cache_t cache;
+ ocf_unlock_fn_t unlock_fn;
+ ocf_mngt_cache_lock_end_t cmpl;
+ void *priv;
+};
+
+static void _ocf_mngt_cache_lock_complete(
+ ocf_async_lock_waiter_t waiter, int error)
+{
+ struct ocf_mngt_cache_lock_context *context;
+ ocf_cache_t cache;
+
+ context = ocf_async_lock_waiter_get_priv(waiter);
+ cache = context->cache;
+
+ if (error) {
+ ocf_mngt_cache_put(cache);
+ goto out;
+ }
+
+ if (env_bit_test(ocf_cache_state_stopping, &cache->cache_state)) {
+ /* Cache already stopping, do not allow any operation */
+ context->unlock_fn(ocf_async_lock_waiter_get_lock(waiter));
+ ocf_mngt_cache_put(cache);
error = -OCF_ERR_CACHE_NOT_EXIST;
- else
- *cache = instance;
+ }
- return error;
+out:
+ context->cmpl(context->cache, context->priv, error);
}
-bool ocf_mngt_is_cache_locked(ocf_cache_t cache)
+static void _ocf_mngt_cache_lock(ocf_cache_t cache,
+ ocf_mngt_cache_lock_end_t cmpl, void *priv,
+ ocf_lock_fn_t lock_fn, ocf_unlock_fn_t unlock_fn)
{
- if (env_rwsem_is_locked(&cache->lock))
- return true;
+ ocf_async_lock_waiter_t waiter;
+ struct ocf_mngt_cache_lock_context *context;
- if (env_atomic_read(&cache->lock_waiter))
- return true;
+ if (ocf_mngt_cache_get(cache))
+ OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_NOT_EXIST);
- return false;
+ waiter = ocf_async_lock_new_waiter(&cache->lock,
+ _ocf_mngt_cache_lock_complete);
+ if (!waiter) {
+ ocf_mngt_cache_put(cache);
+ OCF_CMPL_RET(cache, priv, -OCF_ERR_NO_MEM);
+ }
+
+ context = ocf_async_lock_waiter_get_priv(waiter);
+ context->cache = cache;
+ context->unlock_fn = unlock_fn;
+ context->cmpl = cmpl;
+ context->priv = priv;
+
+ lock_fn(waiter);
+}
+
+static int _ocf_mngt_cache_trylock(ocf_cache_t cache,
+ ocf_trylock_fn_t trylock_fn, ocf_unlock_fn_t unlock_fn)
+{
+ int result;
+
+ if (ocf_mngt_cache_get(cache))
+ return -OCF_ERR_CACHE_NOT_EXIST;
+
+ result = trylock_fn(&cache->lock);
+ if (result)
+ return result;
+
+ if (env_bit_test(ocf_cache_state_stopping, &cache->cache_state)) {
+ /* Cache already stopping, do not allow any operation */
+ unlock_fn(&cache->lock);
+ return -OCF_ERR_CACHE_NOT_EXIST;
+ }
+
+ return 0;
}
static void _ocf_mngt_cache_unlock(ocf_cache_t cache,
- void (*unlock_fn)(env_rwsem *s))
+ ocf_unlock_fn_t unlock_fn)
{
unlock_fn(&cache->lock);
ocf_mngt_cache_put(cache);
}
-void ocf_mngt_cache_unlock(ocf_cache_t cache)
+int ocf_mngt_cache_lock_init(ocf_cache_t cache)
{
- OCF_CHECK_NULL(cache);
- _ocf_mngt_cache_unlock(cache, env_rwsem_up_write);
+ return ocf_async_lock_init(&cache->lock,
+ sizeof(struct ocf_mngt_cache_lock_context));
}
-void ocf_mngt_cache_read_unlock(ocf_cache_t cache)
+void ocf_mngt_cache_lock_deinit(ocf_cache_t cache)
{
- OCF_CHECK_NULL(cache);
- _ocf_mngt_cache_unlock(cache, env_rwsem_up_read);
+ ocf_async_lock_deinit(&cache->lock);
}
-static int _ocf_mngt_cache_lock(ocf_cache_t cache, int (*lock_fn)(env_rwsem *s),
- void (*unlock_fn)(env_rwsem *s))
+void ocf_mngt_cache_lock(ocf_cache_t cache,
+ ocf_mngt_cache_lock_end_t cmpl, void *priv)
{
- int ret;
-
- /* Increment reference counter */
- env_atomic_inc(&cache->ref_count);
-
- env_atomic_inc(&cache->lock_waiter);
- ret = lock_fn(&cache->lock);
- env_atomic_dec(&cache->lock_waiter);
+ OCF_CHECK_NULL(cache);
- if (ret) {
- ocf_mngt_cache_put(cache);
- return ret;
- }
+ _ocf_mngt_cache_lock(cache, cmpl, priv,
+ ocf_async_lock, ocf_async_unlock);
+}
- if (env_bit_test(ocf_cache_state_stopping, &cache->cache_state)) {
- /* Cache already stooping, do not allow any operation */
- ret = -OCF_ERR_CACHE_NOT_EXIST;
- goto unlock;
- }
+int ocf_mngt_cache_trylock(ocf_cache_t cache)
+{
+ OCF_CHECK_NULL(cache);
- return 0;
+ return _ocf_mngt_cache_trylock(cache,
+ ocf_async_trylock, ocf_async_unlock);
+}
-unlock:
- _ocf_mngt_cache_unlock(cache, unlock_fn);
+void ocf_mngt_cache_unlock(ocf_cache_t cache)
+{
+ OCF_CHECK_NULL(cache);
- return ret;
+ _ocf_mngt_cache_unlock(cache, ocf_async_unlock);
}
-int ocf_mngt_cache_lock(ocf_cache_t cache)
+void ocf_mngt_cache_read_lock(ocf_cache_t cache,
+ ocf_mngt_cache_lock_end_t cmpl, void *priv)
{
OCF_CHECK_NULL(cache);
- return _ocf_mngt_cache_lock(cache, env_rwsem_down_write_interruptible,
- env_rwsem_up_write);
+
+ _ocf_mngt_cache_lock(cache, cmpl, priv,
+ ocf_async_read_lock, ocf_async_read_unlock);
}
-int ocf_mngt_cache_read_lock(ocf_cache_t cache)
+int ocf_mngt_cache_read_trylock(ocf_cache_t cache)
{
OCF_CHECK_NULL(cache);
- return _ocf_mngt_cache_lock(cache, env_rwsem_down_read_interruptible,
- env_rwsem_up_read);
+
+ return _ocf_mngt_cache_trylock(cache,
+ ocf_async_read_trylock, ocf_async_read_unlock);
}
-int ocf_mngt_cache_trylock(ocf_cache_t cache)
+void ocf_mngt_cache_read_unlock(ocf_cache_t cache)
{
OCF_CHECK_NULL(cache);
- return _ocf_mngt_cache_lock(cache, env_rwsem_down_write_trylock,
- env_rwsem_up_write);
+
+ _ocf_mngt_cache_unlock(cache, ocf_async_read_unlock);
}
-int ocf_mngt_cache_read_trylock(ocf_cache_t cache)
+bool ocf_mngt_cache_is_locked(ocf_cache_t cache)
{
- OCF_CHECK_NULL(cache);
- return _ocf_mngt_cache_lock(cache, env_rwsem_down_read_trylock,
- env_rwsem_up_read);
+ return ocf_async_is_locked(&cache->lock);
}
/* if cache is either fully initialized or during recovery */
static bool _ocf_mngt_cache_try_get(ocf_cache_t cache)
{
- if (!!cache->valid_ocf_cache_device_t) {
- /* Increase reference counter */
- env_atomic_inc(&cache->ref_count);
- return true;
- }
-
- return false;
+ return !!ocf_refcnt_inc(&cache->refcnt.cache);
}
int ocf_mngt_cache_get(ocf_cache_t cache)
*list = NULL;
*size = 0;
- env_mutex_lock(&ocf_ctx->lock);
+ env_rmutex_lock(&ocf_ctx->lock);
list_for_each_entry(iter, &ocf_ctx->caches, list) {
count++;
}
list_for_each_entry(iter, &ocf_ctx->caches, list) {
-
if (_ocf_mngt_cache_try_get(iter))
(*list)[i++] = iter;
}
}
END:
- env_mutex_unlock(&ocf_ctx->lock);
+ env_rmutex_unlock(&ocf_ctx->lock);
return result;
}