Remove core id from public API
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
parent
a32ca74519
commit
92c7e12549
@ -19,6 +19,11 @@
|
|||||||
* @brief Core start configuration
|
* @brief Core start configuration
|
||||||
*/
|
*/
|
||||||
struct ocf_mngt_core_config {
|
struct ocf_mngt_core_config {
|
||||||
|
/**
|
||||||
|
* @brief OCF core name
|
||||||
|
*/
|
||||||
|
const char *name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief OCF core volume UUID
|
* @brief OCF core volume UUID
|
||||||
*/
|
*/
|
||||||
@ -29,17 +34,6 @@ struct ocf_mngt_core_config {
|
|||||||
*/
|
*/
|
||||||
uint8_t volume_type;
|
uint8_t volume_type;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief OCF core ID number
|
|
||||||
*/
|
|
||||||
ocf_core_id_t core_id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief OCF core name. In case of being NULL, core id is stringified
|
|
||||||
* to core name
|
|
||||||
*/
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add core to pool if cache isn't present or add core to
|
* @brief Add core to pool if cache isn't present or add core to
|
||||||
* earlier loaded cache
|
* earlier loaded cache
|
||||||
@ -66,7 +60,6 @@ struct ocf_mngt_core_config {
|
|||||||
static inline void ocf_mngt_core_config_set_default(
|
static inline void ocf_mngt_core_config_set_default(
|
||||||
struct ocf_mngt_core_config *cfg)
|
struct ocf_mngt_core_config *cfg)
|
||||||
{
|
{
|
||||||
cfg->core_id = OCF_CORE_ID_INVALID;
|
|
||||||
cfg->try_add = false;
|
cfg->try_add = false;
|
||||||
cfg->seq_cutoff_threshold = 1024;
|
cfg->seq_cutoff_threshold = 1024;
|
||||||
cfg->user_metadata.data = NULL;
|
cfg->user_metadata.data = NULL;
|
||||||
|
@ -79,47 +79,6 @@ void ocf_mngt_core_clear_uuid_metadata(ocf_core_t core)
|
|||||||
ocf_mngt_core_set_uuid_metadata(core, &uuid, NULL);
|
ocf_mngt_core_set_uuid_metadata(core, &uuid, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int _ocf_mngt_cache_try_add_core(ocf_cache_t cache, ocf_core_t *core,
|
|
||||||
struct ocf_mngt_core_config *cfg)
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
ocf_core_t tmp_core;
|
|
||||||
ocf_volume_t volume;
|
|
||||||
|
|
||||||
tmp_core = &cache->core[cfg->core_id];
|
|
||||||
volume = &tmp_core->volume;
|
|
||||||
|
|
||||||
if (ocf_ctx_get_volume_type_id(cache->owner, volume->type) !=
|
|
||||||
cfg->volume_type) {
|
|
||||||
result = -OCF_ERR_INVAL_VOLUME_TYPE;
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ocf_volume_open(volume, NULL);
|
|
||||||
if (result)
|
|
||||||
goto error_out;
|
|
||||||
|
|
||||||
if (!ocf_volume_get_length(volume)) {
|
|
||||||
result = -OCF_ERR_CORE_NOT_AVAIL;
|
|
||||||
goto error_after_open;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp_core->opened = true;
|
|
||||||
|
|
||||||
if (!(--cache->ocf_core_inactive_count))
|
|
||||||
env_bit_clear(ocf_cache_state_incomplete, &cache->cache_state);
|
|
||||||
|
|
||||||
*core = tmp_core;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error_after_open:
|
|
||||||
ocf_volume_close(volume);
|
|
||||||
error_out:
|
|
||||||
*core = NULL;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ocf_cache_add_core_context {
|
struct ocf_cache_add_core_context {
|
||||||
ocf_mngt_cache_add_core_end_t cmpl;
|
ocf_mngt_cache_add_core_end_t cmpl;
|
||||||
void *priv;
|
void *priv;
|
||||||
@ -140,20 +99,21 @@ struct ocf_cache_add_core_context {
|
|||||||
static void _ocf_mngt_cache_add_core_handle_error(
|
static void _ocf_mngt_cache_add_core_handle_error(
|
||||||
struct ocf_cache_add_core_context *context)
|
struct ocf_cache_add_core_context *context)
|
||||||
{
|
{
|
||||||
struct ocf_mngt_core_config *cfg = &context->cfg;
|
|
||||||
ocf_cache_t cache = context->cache;
|
ocf_cache_t cache = context->cache;
|
||||||
ocf_core_t core = context->core;
|
ocf_core_t core = context->core;
|
||||||
|
ocf_core_id_t core_id;
|
||||||
ocf_volume_t volume;
|
ocf_volume_t volume;
|
||||||
ocf_cleaning_t clean_type;
|
ocf_cleaning_t clean_type;
|
||||||
|
|
||||||
if (!core)
|
if (!core)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
core_id = ocf_core_get_id(core);
|
||||||
volume = &core->volume;
|
volume = &core->volume;
|
||||||
clean_type = cache->conf_meta->cleaning_policy_type;
|
clean_type = cache->conf_meta->cleaning_policy_type;
|
||||||
|
|
||||||
if (context->flags.counters_allocated) {
|
if (context->flags.counters_allocated) {
|
||||||
env_bit_clear(cfg->core_id,
|
env_bit_clear(core_id,
|
||||||
cache->conf_meta->valid_core_bitmap);
|
cache->conf_meta->valid_core_bitmap);
|
||||||
core->conf_meta->added = false;
|
core->conf_meta->added = false;
|
||||||
core->opened = false;
|
core->opened = false;
|
||||||
@ -165,7 +125,7 @@ static void _ocf_mngt_cache_add_core_handle_error(
|
|||||||
if (context->flags.clean_pol_added) {
|
if (context->flags.clean_pol_added) {
|
||||||
if (cleaning_policy_ops[clean_type].remove_core)
|
if (cleaning_policy_ops[clean_type].remove_core)
|
||||||
cleaning_policy_ops[clean_type].remove_core(cache,
|
cleaning_policy_ops[clean_type].remove_core(cache,
|
||||||
cfg->core_id);
|
core_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->flags.volume_opened)
|
if (context->flags.volume_opened)
|
||||||
@ -178,123 +138,6 @@ static void _ocf_mngt_cache_add_core_handle_error(
|
|||||||
ocf_mngt_core_clear_uuid_metadata(core);
|
ocf_mngt_core_clear_uuid_metadata(core);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_cache_add_core_flush_sb_complete(void *priv, int error)
|
|
||||||
{
|
|
||||||
struct ocf_cache_add_core_context *context = priv;
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_WRITE_CACHE);
|
|
||||||
|
|
||||||
/* Increase value of added cores */
|
|
||||||
context->cache->conf_meta->core_count++;
|
|
||||||
|
|
||||||
ocf_pipeline_next(context->pipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _ocf_mngt_cache_add_core(ocf_cache_t cache,
|
|
||||||
struct ocf_cache_add_core_context *context)
|
|
||||||
{
|
|
||||||
struct ocf_mngt_core_config *cfg = &context->cfg;
|
|
||||||
ocf_core_t core;
|
|
||||||
struct ocf_volume_uuid new_uuid;
|
|
||||||
ocf_volume_t volume;
|
|
||||||
ocf_volume_type_t type;
|
|
||||||
ocf_seq_no_t core_sequence_no;
|
|
||||||
ocf_cleaning_t clean_type;
|
|
||||||
uint64_t length;
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
core = ocf_cache_get_core(cache, cfg->core_id);
|
|
||||||
context->core = core;
|
|
||||||
|
|
||||||
volume = &core->volume;
|
|
||||||
volume->cache = cache;
|
|
||||||
|
|
||||||
/* Set uuid */
|
|
||||||
result = ocf_mngt_core_set_uuid_metadata(core, &cfg->uuid, &new_uuid);
|
|
||||||
if (result)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, result);
|
|
||||||
|
|
||||||
context->flags.uuid_set = true;
|
|
||||||
|
|
||||||
type = ocf_ctx_get_volume_type(cache->owner, cfg->volume_type);
|
|
||||||
if (!type) {
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline,
|
|
||||||
-OCF_ERR_INVAL_VOLUME_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ocf_volume_init(volume, type, &new_uuid, false);
|
|
||||||
if (result)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, result);
|
|
||||||
|
|
||||||
context->flags.volume_inited = true;
|
|
||||||
|
|
||||||
if (cfg->user_metadata.data && cfg->user_metadata.size > 0) {
|
|
||||||
result = ocf_mngt_core_set_user_metadata(core,
|
|
||||||
cfg->user_metadata.data,
|
|
||||||
cfg->user_metadata.size);
|
|
||||||
if (result)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ocf_volume_open(volume, NULL);
|
|
||||||
if (result)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, result);
|
|
||||||
|
|
||||||
context->flags.volume_opened = true;
|
|
||||||
|
|
||||||
length = ocf_volume_get_length(volume);
|
|
||||||
if (!length)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_CORE_NOT_AVAIL);
|
|
||||||
|
|
||||||
core->conf_meta->length = length;
|
|
||||||
|
|
||||||
clean_type = cache->conf_meta->cleaning_policy_type;
|
|
||||||
if (ocf_cache_is_device_attached(cache) &&
|
|
||||||
cleaning_policy_ops[clean_type].add_core) {
|
|
||||||
result = cleaning_policy_ops[clean_type].add_core(cache,
|
|
||||||
cfg->core_id);
|
|
||||||
if (result)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, result);
|
|
||||||
|
|
||||||
context->flags.clean_pol_added = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* When adding new core to cache, allocate stat counters */
|
|
||||||
core->counters =
|
|
||||||
env_zalloc(sizeof(*core->counters), ENV_MEM_NORMAL);
|
|
||||||
if (!core->counters)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_NO_MEM);
|
|
||||||
|
|
||||||
context->flags.counters_allocated = true;
|
|
||||||
|
|
||||||
/* When adding new core to cache, reset all core/cache statistics */
|
|
||||||
ocf_core_stats_initialize(core);
|
|
||||||
env_atomic_set(&core->runtime_meta->cached_clines, 0);
|
|
||||||
env_atomic_set(&core->runtime_meta->dirty_clines, 0);
|
|
||||||
env_atomic64_set(&core->runtime_meta->dirty_since, 0);
|
|
||||||
|
|
||||||
/* In metadata mark data this core was added into cache */
|
|
||||||
env_bit_set(cfg->core_id, cache->conf_meta->valid_core_bitmap);
|
|
||||||
core->conf_meta->added = true;
|
|
||||||
core->opened = true;
|
|
||||||
|
|
||||||
/* Set default cache parameters for sequential */
|
|
||||||
core->conf_meta->seq_cutoff_policy = ocf_seq_cutoff_policy_default;
|
|
||||||
core->conf_meta->seq_cutoff_threshold = cfg->seq_cutoff_threshold;
|
|
||||||
|
|
||||||
/* Add core sequence number for atomic metadata matching */
|
|
||||||
core_sequence_no = _ocf_mngt_get_core_seq_no(cache);
|
|
||||||
if (core_sequence_no == OCF_SEQ_NO_INVALID)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_TOO_MANY_CORES);
|
|
||||||
|
|
||||||
core->conf_meta->seq_no = core_sequence_no;
|
|
||||||
|
|
||||||
/* Update super-block with core device addition */
|
|
||||||
ocf_metadata_flush_superblock(cache,
|
|
||||||
_ocf_mngt_cache_add_core_flush_sb_complete, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long _ffz(unsigned long word)
|
static unsigned long _ffz(unsigned long word)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -330,118 +173,21 @@ static unsigned long _ocf_mngt_find_first_free_core(const unsigned long *bitmap)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __ocf_mngt_lookup_core_uuid(ocf_cache_t cache,
|
static int ocf_mngt_find_free_core(ocf_cache_t cache, ocf_core_t *core)
|
||||||
struct ocf_mngt_core_config *cfg)
|
|
||||||
{
|
{
|
||||||
int i;
|
ocf_core_id_t core_id;
|
||||||
|
ocf_core_t tmp_core;
|
||||||
|
|
||||||
for (i = 0; i < OCF_CORE_MAX; i++) {
|
core_id = _ocf_mngt_find_first_free_core(
|
||||||
ocf_core_t core = &cache->core[i];
|
|
||||||
|
|
||||||
if (!env_bit_test(i, cache->conf_meta->valid_core_bitmap))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (cache->core[i].opened)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ocf_ctx_get_volume_type_id(cache->owner, core->volume.type)
|
|
||||||
!= cfg->volume_type) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!env_strncmp(core->volume.uuid.data, cfg->uuid.data,
|
|
||||||
OCF_MIN(core->volume.uuid.size,
|
|
||||||
cfg->uuid.size))) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return OCF_CORE_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __ocf_mngt_try_find_core_id(ocf_cache_t cache,
|
|
||||||
struct ocf_mngt_core_config *cfg, ocf_core_id_t tmp_core_id)
|
|
||||||
{
|
|
||||||
if (tmp_core_id == OCF_CORE_MAX) {
|
|
||||||
ocf_cache_log(cache, log_err, "Core with given uuid not found "
|
|
||||||
"in cache metadata\n");
|
|
||||||
return -OCF_ERR_CORE_NOT_AVAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg->core_id == OCF_CORE_MAX) {
|
|
||||||
cfg->core_id = tmp_core_id;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg->core_id != tmp_core_id) {
|
|
||||||
ocf_cache_log(cache, log_err,
|
|
||||||
"Given core id doesn't match with metadata\n");
|
|
||||||
return -OCF_ERR_CORE_NOT_AVAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cfg->core_id = tmp_core_id;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __ocf_mngt_find_core_id(ocf_cache_t cache,
|
|
||||||
struct ocf_mngt_core_config *cfg, ocf_core_id_t tmp_core_id)
|
|
||||||
{
|
|
||||||
if (tmp_core_id != OCF_CORE_MAX) {
|
|
||||||
ocf_cache_log(cache, log_err,
|
|
||||||
"Core ID already added as inactive with id:"
|
|
||||||
" %hu.\n", tmp_core_id);
|
|
||||||
return -OCF_ERR_CORE_NOT_AVAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg->core_id == OCF_CORE_MAX) {
|
|
||||||
ocf_cache_log(cache, log_debug, "Core ID is unspecified - "
|
|
||||||
"will set first available number\n");
|
|
||||||
|
|
||||||
/* Core is unspecified */
|
|
||||||
cfg->core_id = _ocf_mngt_find_first_free_core(
|
|
||||||
cache->conf_meta->valid_core_bitmap);
|
cache->conf_meta->valid_core_bitmap);
|
||||||
/* no need to check if find_first_zero_bit failed and
|
|
||||||
* *core_id == MAX_CORE_OBJS_PER_CACHE, as above there is check
|
|
||||||
* for core_count being greater or equal to
|
|
||||||
* MAX_CORE_OBJS_PER_CACHE
|
|
||||||
*/
|
|
||||||
} else if (cfg->core_id < OCF_CORE_MAX) {
|
|
||||||
/* check if id is not used already */
|
|
||||||
if (env_bit_test(cfg->core_id,
|
|
||||||
cache->conf_meta->valid_core_bitmap)) {
|
|
||||||
ocf_cache_log(cache, log_debug,
|
|
||||||
"Core ID already allocated: %d.\n",
|
|
||||||
cfg->core_id);
|
|
||||||
return -OCF_ERR_CORE_NOT_AVAIL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ocf_cache_log(cache, log_err,
|
|
||||||
"Core ID exceeds maximum of %d.\n",
|
|
||||||
OCF_CORE_MAX);
|
|
||||||
return -OCF_ERR_CORE_NOT_AVAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
tmp_core = ocf_cache_get_core(cache, core_id);
|
||||||
}
|
if (!tmp_core)
|
||||||
|
|
||||||
static int _ocf_mngt_find_core_id(ocf_cache_t cache,
|
|
||||||
struct ocf_mngt_core_config *cfg)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
ocf_core_id_t tmp_core_id;
|
|
||||||
|
|
||||||
if (cache->conf_meta->core_count >= OCF_CORE_MAX)
|
|
||||||
return -OCF_ERR_TOO_MANY_CORES;
|
return -OCF_ERR_TOO_MANY_CORES;
|
||||||
|
|
||||||
tmp_core_id = __ocf_mngt_lookup_core_uuid(cache, cfg);
|
*core = tmp_core;
|
||||||
|
|
||||||
if (cfg->try_add)
|
return 0;
|
||||||
result = __ocf_mngt_try_find_core_id(cache, cfg, tmp_core_id);
|
|
||||||
else
|
|
||||||
result = __ocf_mngt_find_core_id(cache, cfg, tmp_core_id);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ocf_mngt_core_init_front_volume(ocf_core_t core)
|
int ocf_mngt_core_init_front_volume(ocf_core_t core)
|
||||||
@ -469,30 +215,117 @@ int ocf_mngt_core_init_front_volume(ocf_core_t core)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ocf_mngt_cache_add_core_prepare(ocf_pipeline_t pipeline,
|
static void ocf_mngt_cache_try_add_core_prepare(ocf_pipeline_t pipeline,
|
||||||
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
|
{
|
||||||
|
struct ocf_cache_add_core_context *context = priv;
|
||||||
|
struct ocf_mngt_core_config *cfg = &context->cfg;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
ocf_core_t core;
|
||||||
|
ocf_volume_t volume;
|
||||||
|
ocf_volume_type_t type;
|
||||||
|
ocf_ctx_t ctx = cache->owner;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = ocf_core_get_by_name(cache, cfg->name, &core);
|
||||||
|
if (result)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (core->opened) {
|
||||||
|
result = -OCF_ERR_INVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
volume = ocf_core_get_volume(core);
|
||||||
|
type = ocf_volume_get_type(volume);
|
||||||
|
|
||||||
|
if (ocf_ctx_get_volume_type_id(ctx, type) != cfg->volume_type) {
|
||||||
|
result = -OCF_ERR_INVAL_VOLUME_TYPE;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env_strncmp(volume->uuid.data, cfg->uuid.data,
|
||||||
|
OCF_MIN(volume->uuid.size, cfg->uuid.size))) {
|
||||||
|
result = -OCF_ERR_INVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->core = core;
|
||||||
|
|
||||||
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
|
|
||||||
|
err:
|
||||||
|
ocf_cache_log(cache, log_err, "Core with given uuid not found "
|
||||||
|
"in cache metadata\n");
|
||||||
|
OCF_PL_FINISH_RET(pipeline, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ocf_mngt_cache_try_add_core_insert(ocf_pipeline_t pipeline,
|
||||||
void *priv, ocf_pipeline_arg_t arg)
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
{
|
{
|
||||||
struct ocf_cache_add_core_context *context = priv;
|
struct ocf_cache_add_core_context *context = priv;
|
||||||
ocf_cache_t cache = context->cache;
|
ocf_cache_t cache = context->cache;
|
||||||
|
ocf_core_t core = context->core;
|
||||||
|
ocf_volume_t volume;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
ocf_core_log(core, log_debug, "Inserting core\n");
|
||||||
|
|
||||||
|
volume = ocf_core_get_volume(core);
|
||||||
|
|
||||||
|
result = ocf_volume_open(volume, NULL);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, result);
|
||||||
|
|
||||||
|
if (!ocf_volume_get_length(volume)) {
|
||||||
|
result = -OCF_ERR_CORE_NOT_AVAIL;
|
||||||
|
goto error_after_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
core->opened = true;
|
||||||
|
|
||||||
|
if (!(--cache->ocf_core_inactive_count))
|
||||||
|
env_bit_clear(ocf_cache_state_incomplete, &cache->cache_state);
|
||||||
|
|
||||||
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
|
|
||||||
|
error_after_open:
|
||||||
|
ocf_volume_close(volume);
|
||||||
|
OCF_PL_FINISH_RET(pipeline, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ocf_mngt_cache_add_core_prepare(ocf_pipeline_t pipeline,
|
||||||
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
|
{
|
||||||
|
struct ocf_cache_add_core_context *context = priv;
|
||||||
|
struct ocf_mngt_core_config *cfg = &context->cfg;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
ocf_core_t core;
|
ocf_core_t core;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = _ocf_mngt_find_core_id(cache, &context->cfg);
|
result = ocf_core_get_by_name(cache, cfg->name, &core);
|
||||||
if (result)
|
if (!result)
|
||||||
OCF_PL_FINISH_RET(context->pipeline, result);
|
|
||||||
|
|
||||||
if (!context->cfg.name)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_INVAL);
|
|
||||||
|
|
||||||
result = ocf_core_get_by_name(cache, context->cfg.name, &core);
|
|
||||||
if (!result && !context->cfg.try_add)
|
|
||||||
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_CORE_EXIST);
|
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_CORE_EXIST);
|
||||||
|
|
||||||
result = ocf_mngt_core_set_name(&cache->core[context->cfg.core_id],
|
result = ocf_mngt_find_free_core(cache, &core);
|
||||||
context->cfg.name);
|
|
||||||
if (result)
|
if (result)
|
||||||
OCF_PL_FINISH_RET(context->pipeline, result);
|
OCF_PL_FINISH_RET(context->pipeline, result);
|
||||||
|
|
||||||
|
context->core = core;
|
||||||
|
|
||||||
|
ocf_pipeline_next(context->pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_cache_add_core_flush_sb_complete(void *priv, int error)
|
||||||
|
{
|
||||||
|
struct ocf_cache_add_core_context *context = priv;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_WRITE_CACHE);
|
||||||
|
|
||||||
|
/* Increase value of added cores */
|
||||||
|
context->cache->conf_meta->core_count++;
|
||||||
|
|
||||||
ocf_pipeline_next(context->pipeline);
|
ocf_pipeline_next(context->pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,20 +333,109 @@ static void ocf_mngt_cache_add_core_insert(ocf_pipeline_t pipeline,
|
|||||||
void *priv, ocf_pipeline_arg_t arg)
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
{
|
{
|
||||||
struct ocf_cache_add_core_context *context = priv;
|
struct ocf_cache_add_core_context *context = priv;
|
||||||
|
struct ocf_mngt_core_config *cfg = &context->cfg;
|
||||||
ocf_cache_t cache = context->cache;
|
ocf_cache_t cache = context->cache;
|
||||||
const char *core_name = context->cfg.name;
|
ocf_core_t core = context->core;
|
||||||
int result;
|
ocf_core_id_t core_id;
|
||||||
|
struct ocf_volume_uuid new_uuid;
|
||||||
|
ocf_volume_t volume;
|
||||||
|
ocf_volume_type_t type;
|
||||||
|
ocf_seq_no_t core_sequence_no;
|
||||||
|
ocf_cleaning_t clean_type;
|
||||||
|
uint64_t length;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
ocf_cache_log(cache, log_debug, "Inserting core %s\n", core_name);
|
ocf_cache_log(cache, log_debug, "Inserting core %s\n", cfg->name);
|
||||||
|
|
||||||
if (context->cfg.try_add) {
|
volume = ocf_core_get_volume(core);
|
||||||
result = _ocf_mngt_cache_try_add_core(cache, &context->core,
|
volume->cache = cache;
|
||||||
&context->cfg);
|
core_id = ocf_core_get_id(core);
|
||||||
|
|
||||||
OCF_PL_NEXT_ON_SUCCESS_RET(context->pipeline, result);
|
result = ocf_mngt_core_set_name(core, cfg->name);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, result);
|
||||||
|
|
||||||
|
/* Set uuid */
|
||||||
|
result = ocf_mngt_core_set_uuid_metadata(core, &cfg->uuid, &new_uuid);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, result);
|
||||||
|
|
||||||
|
context->flags.uuid_set = true;
|
||||||
|
|
||||||
|
type = ocf_ctx_get_volume_type(cache->owner, cfg->volume_type);
|
||||||
|
if (!type)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL_VOLUME_TYPE);
|
||||||
|
|
||||||
|
result = ocf_volume_init(volume, type, &new_uuid, false);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, result);
|
||||||
|
|
||||||
|
context->flags.volume_inited = true;
|
||||||
|
|
||||||
|
if (cfg->user_metadata.data && cfg->user_metadata.size > 0) {
|
||||||
|
result = ocf_mngt_core_set_user_metadata(core,
|
||||||
|
cfg->user_metadata.data,
|
||||||
|
cfg->user_metadata.size);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ocf_mngt_cache_add_core(cache, context);
|
result = ocf_volume_open(volume, NULL);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, result);
|
||||||
|
|
||||||
|
context->flags.volume_opened = true;
|
||||||
|
|
||||||
|
length = ocf_volume_get_length(volume);
|
||||||
|
if (!length)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_CORE_NOT_AVAIL);
|
||||||
|
|
||||||
|
core->conf_meta->length = length;
|
||||||
|
|
||||||
|
clean_type = cache->conf_meta->cleaning_policy_type;
|
||||||
|
if (ocf_cache_is_device_attached(cache) &&
|
||||||
|
cleaning_policy_ops[clean_type].add_core) {
|
||||||
|
result = cleaning_policy_ops[clean_type].add_core(cache,
|
||||||
|
core_id);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, result);
|
||||||
|
|
||||||
|
context->flags.clean_pol_added = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When adding new core to cache, allocate stat counters */
|
||||||
|
core->counters =
|
||||||
|
env_zalloc(sizeof(*core->counters), ENV_MEM_NORMAL);
|
||||||
|
if (!core->counters)
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_NO_MEM);
|
||||||
|
|
||||||
|
context->flags.counters_allocated = true;
|
||||||
|
|
||||||
|
/* When adding new core to cache, reset all core/cache statistics */
|
||||||
|
ocf_core_stats_initialize(core);
|
||||||
|
env_atomic_set(&core->runtime_meta->cached_clines, 0);
|
||||||
|
env_atomic_set(&core->runtime_meta->dirty_clines, 0);
|
||||||
|
env_atomic64_set(&core->runtime_meta->dirty_since, 0);
|
||||||
|
|
||||||
|
/* In metadata mark data this core was added into cache */
|
||||||
|
env_bit_set(core_id, cache->conf_meta->valid_core_bitmap);
|
||||||
|
core->conf_meta->added = true;
|
||||||
|
core->opened = true;
|
||||||
|
|
||||||
|
/* Set default cache parameters for sequential */
|
||||||
|
core->conf_meta->seq_cutoff_policy = ocf_seq_cutoff_policy_default;
|
||||||
|
core->conf_meta->seq_cutoff_threshold = cfg->seq_cutoff_threshold;
|
||||||
|
|
||||||
|
/* Add core sequence number for atomic metadata matching */
|
||||||
|
core_sequence_no = _ocf_mngt_get_core_seq_no(cache);
|
||||||
|
if (core_sequence_no == OCF_SEQ_NO_INVALID)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_TOO_MANY_CORES);
|
||||||
|
|
||||||
|
core->conf_meta->seq_no = core_sequence_no;
|
||||||
|
|
||||||
|
/* Update super-block with core device addition */
|
||||||
|
ocf_metadata_flush_superblock(cache,
|
||||||
|
_ocf_mngt_cache_add_core_flush_sb_complete, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ocf_mngt_cache_add_core_init_front_volume(ocf_pipeline_t pipeline,
|
static void ocf_mngt_cache_add_core_init_front_volume(ocf_pipeline_t pipeline,
|
||||||
@ -557,7 +479,18 @@ out:
|
|||||||
ocf_pipeline_destroy(context->pipeline);
|
ocf_pipeline_destroy(context->pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ocf_pipeline_properties ocf_mngt_cache_add_core_pipeline_properties = {
|
struct ocf_pipeline_properties ocf_mngt_cache_try_add_core_pipeline_props = {
|
||||||
|
.priv_size = sizeof(struct ocf_cache_add_core_context),
|
||||||
|
.finish = ocf_mngt_cache_add_core_finish,
|
||||||
|
.steps = {
|
||||||
|
OCF_PL_STEP(ocf_mngt_cache_try_add_core_prepare),
|
||||||
|
OCF_PL_STEP(ocf_mngt_cache_try_add_core_insert),
|
||||||
|
OCF_PL_STEP(ocf_mngt_cache_add_core_init_front_volume),
|
||||||
|
OCF_PL_STEP_TERMINATOR(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ocf_pipeline_properties ocf_mngt_cache_add_core_pipeline_props = {
|
||||||
.priv_size = sizeof(struct ocf_cache_add_core_context),
|
.priv_size = sizeof(struct ocf_cache_add_core_context),
|
||||||
.finish = ocf_mngt_cache_add_core_finish,
|
.finish = ocf_mngt_cache_add_core_finish,
|
||||||
.steps = {
|
.steps = {
|
||||||
@ -583,8 +516,12 @@ void ocf_mngt_cache_add_core(ocf_cache_t cache,
|
|||||||
if (!cache->mngt_queue)
|
if (!cache->mngt_queue)
|
||||||
OCF_CMPL_RET(cache, NULL, priv, -OCF_ERR_INVAL);
|
OCF_CMPL_RET(cache, NULL, priv, -OCF_ERR_INVAL);
|
||||||
|
|
||||||
result = ocf_pipeline_create(&pipeline, cache,
|
if (!cfg->name)
|
||||||
&ocf_mngt_cache_add_core_pipeline_properties);
|
OCF_CMPL_RET(cache, NULL, priv, -OCF_ERR_INVAL);
|
||||||
|
|
||||||
|
result = ocf_pipeline_create(&pipeline, cache, cfg->try_add ?
|
||||||
|
&ocf_mngt_cache_try_add_core_pipeline_props :
|
||||||
|
&ocf_mngt_cache_add_core_pipeline_props);
|
||||||
if (result)
|
if (result)
|
||||||
OCF_CMPL_RET(cache, NULL, priv, -OCF_ERR_NO_MEM);
|
OCF_CMPL_RET(cache, NULL, priv, -OCF_ERR_NO_MEM);
|
||||||
|
|
||||||
@ -866,7 +803,7 @@ void ocf_mngt_cache_detach_core(ocf_core_t core,
|
|||||||
context->cmpl = cmpl;
|
context->cmpl = cmpl;
|
||||||
context->priv = priv;
|
context->priv = priv;
|
||||||
context->pipeline = pipeline;
|
context->pipeline = pipeline;
|
||||||
context->cache = ocf_core_get_cache(core);
|
context->cache = cache;
|
||||||
context->core = core;
|
context->core = core;
|
||||||
context->core_name = ocf_core_get_name(core);
|
context->core_name = ocf_core_get_name(core);
|
||||||
|
|
||||||
|
@ -172,6 +172,9 @@ struct ocf_cache {
|
|||||||
static inline ocf_core_t ocf_cache_get_core(ocf_cache_t cache,
|
static inline ocf_core_t ocf_cache_get_core(ocf_cache_t cache,
|
||||||
ocf_core_id_t core_id)
|
ocf_core_id_t core_id)
|
||||||
{
|
{
|
||||||
|
if (core_id >= OCF_CORE_MAX)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return &cache->core[core_id];
|
return &cache->core[core_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user