From 901b39031fb8e728d70fa3374298ab236b2c1978 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Sat, 20 Jul 2019 12:49:57 +0200 Subject: [PATCH] Ensure that cache name is set and unique Signed-off-by: Robert Baldyga --- inc/ocf_err.h | 4 ++-- inc/ocf_mngt.h | 23 ++++++++++++++++++++--- src/mngt/ocf_mngt_cache.c | 25 +++++++++++++++---------- src/mngt/ocf_mngt_common.c | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 15 deletions(-) diff --git a/inc/ocf_err.h b/inc/ocf_err.h index b87c41f..10ecc12 100644 --- a/inc/ocf_err.h +++ b/inc/ocf_err.h @@ -57,10 +57,10 @@ typedef enum { /** Start cache failure */ OCF_ERR_START_CACHE_FAIL, - /** Cache ID does not exist */ + /** Cache ID/name does not exist */ OCF_ERR_CACHE_NOT_EXIST, - /** Cache ID already exists */ + /** Cache ID/name already exists */ OCF_ERR_CACHE_EXIST, /** Too many core devices in cache */ diff --git a/inc/ocf_mngt.h b/inc/ocf_mngt.h index 5029110..2fb117d 100644 --- a/inc/ocf_mngt.h +++ b/inc/ocf_mngt.h @@ -101,6 +101,22 @@ uint32_t ocf_mngt_cache_get_count(ocf_ctx_t ctx); */ int ocf_mngt_cache_get_by_id(ocf_ctx_t ctx, ocf_cache_id_t id, ocf_cache_t *cache); +/** + * @brief Get OCF cache by name + * + * @note This function on success also increases reference counter + * in given cache + * + * @param[in] ctx OCF context + * @param[in] name OCF cache name + * @param[out] cache OCF cache handle + * + * @retval 0 Get cache successfully + * @retval -OCF_ERR_CACHE_NOT_EXIST Cache with given name doesn't exist + */ +int ocf_mngt_cache_get_by_name(ocf_ctx_t ctx, const char* name, + ocf_cache_t *cache); + /** * @brief Increment reference counter of cache * @@ -247,8 +263,7 @@ struct ocf_mngt_cache_config { ocf_cache_id_t id; /** - * @brief Cache name. In case of being NULL, cache id is stringified to - * cache name + * @brief Cache name */ const char *name; @@ -309,13 +324,15 @@ struct ocf_mngt_cache_config { /** * @brief Initialize core config to default values * + * @note This function doesn't initialize name field which has no default + * value and is required to be set by user. + * * @param[in] cfg Cache config stucture */ static inline void ocf_mngt_cache_config_set_default( struct ocf_mngt_cache_config *cfg) { cfg->id = OCF_CACHE_ID_INVALID; - cfg->name = NULL; cfg->cache_mode = ocf_cache_mode_default; cfg->eviction_policy = ocf_eviction_default; cfg->promotion_policy = ocf_promotion_default; diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index 4fd6e22..4f57aa8 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -726,18 +726,20 @@ static int _ocf_mngt_init_prepare_cache(struct ocf_cache_mngt_init_params *param } } - if (cfg->name) { - ret = env_strncpy(cache_name, sizeof(cache_name) - 1, - cfg->name, sizeof(cache_name) - 1); - if (ret) - goto out; - } else { - ret = snprintf(cache_name, sizeof(cache_name), - "cache%hu", param->id); - if (ret < 0) - goto out; + /* Check if cache with specified name exists */ + ret = ocf_mngt_cache_get_by_name(param->ctx, cfg->name, &cache); + if (!ret) { + ocf_mngt_cache_put(cache); + /* Cache already exist */ + ret = -OCF_ERR_CACHE_EXIST; + goto out; } + ret = env_strncpy(cache_name, sizeof(cache_name), + cfg->name, sizeof(cache_name)); + if (ret) + goto out; + ocf_log(param->ctx, log_info, "Inserting cache %s\n", cache_name); ret = _ocf_mngt_init_new_cache(param); @@ -1643,6 +1645,9 @@ static int _ocf_mngt_cache_validate_cfg(struct ocf_mngt_cache_config *cfg) if (cfg->id > OCF_CACHE_ID_MAX) return -OCF_ERR_INVAL; + if (!cfg->name) + return -OCF_ERR_INVAL; + if (!ocf_cache_mode_is_valid(cfg->cache_mode)) return -OCF_ERR_INVALID_CACHE_MODE; diff --git a/src/mngt/ocf_mngt_common.c b/src/mngt/ocf_mngt_common.c index 158a07d..528dd40 100644 --- a/src/mngt/ocf_mngt_common.c +++ b/src/mngt/ocf_mngt_common.c @@ -183,6 +183,44 @@ int ocf_mngt_cache_get_by_id(ocf_ctx_t ocf_ctx, ocf_cache_id_t id, ocf_cache_t * return error; } +int ocf_mngt_cache_get_by_name(ocf_ctx_t ctx, const char *name, + ocf_cache_t *cache) +{ + struct ocf_cache *instance = NULL; + struct ocf_cache *iter = NULL; + + OCF_CHECK_NULL(ctx); + OCF_CHECK_NULL(cache); + + /* Lock caches list */ + env_rmutex_lock(&ctx->lock); + + list_for_each_entry(iter, &ctx->caches, list) { + if (!env_strncmp(ocf_cache_get_name(iter), name, + OCF_CACHE_NAME_SIZE)) { + instance = iter; + break; + } + } + + if (instance) { + /* if cache is either fully initialized or during recovery */ + if (!ocf_refcnt_inc(&instance->refcnt.cache)) { + /* Cache not initialized yet */ + instance = NULL; + } + } + + 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);