]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/spdk/ocf/src/mngt/ocf_mngt_common.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / ocf / src / mngt / ocf_mngt_common.c
index a8d758f35ca69161ada402d120c08dc0ae953dfd..7e0022c879db88496aee6d7fcdc2e8222ba22aeb 100644 (file)
@@ -5,36 +5,41 @@
 
 #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) {
@@ -44,24 +49,23 @@ void cache_mng_core_remove_from_cleaning_pol(struct ocf_cache *cache,
                }
        }
 
-       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) {
@@ -78,76 +82,79 @@ void cache_mng_core_deinit_attached_meta(struct ocf_cache *cache, int core_id)
                }
 
                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;
                }
@@ -155,124 +162,182 @@ int ocf_mngt_cache_get_by_id(ocf_ctx_t ocf_ctx, ocf_cache_id_t id, ocf_cache_t *
 
        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)
@@ -293,7 +358,7 @@ static int _ocf_mngt_cache_get_list_cpy(ocf_ctx_t ocf_ctx, ocf_cache_t **list,
        *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++;
@@ -309,7 +374,6 @@ static int _ocf_mngt_cache_get_list_cpy(ocf_ctx_t ocf_ctx, ocf_cache_t **list,
        }
 
        list_for_each_entry(iter, &ocf_ctx->caches, list) {
-
                if (_ocf_mngt_cache_try_get(iter))
                        (*list)[i++] = iter;
        }
@@ -323,7 +387,7 @@ static int _ocf_mngt_cache_get_list_cpy(ocf_ctx_t ocf_ctx, ocf_cache_t **list,
        }
 
 END:
-       env_mutex_unlock(&ocf_ctx->lock);
+       env_rmutex_unlock(&ocf_ctx->lock);
        return result;
 }