Add cache activation from passive state
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
parent
cc22c57cb7
commit
7b38ad205c
@ -128,6 +128,12 @@ typedef enum {
|
|||||||
|
|
||||||
/** Core with the uuid already exists */
|
/** Core with the uuid already exists */
|
||||||
OCF_ERR_CORE_UUID_EXISTS,
|
OCF_ERR_CORE_UUID_EXISTS,
|
||||||
|
|
||||||
|
/** Cache initialized with wrong metadata layout */
|
||||||
|
OCF_ERR_METADATA_LAYOUT_MISMATCH,
|
||||||
|
|
||||||
|
/** Cache initialized with wrong cache line size */
|
||||||
|
OCF_ERR_CACHE_LINE_SIZE_MISMATCH,
|
||||||
} ocf_error_t;
|
} ocf_error_t;
|
||||||
|
|
||||||
#endif /* __OCF_ERR_H__ */
|
#endif /* __OCF_ERR_H__ */
|
||||||
|
@ -536,6 +536,28 @@ void ocf_mngt_cache_bind(ocf_cache_t cache,
|
|||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_device_config *cfg,
|
||||||
ocf_mngt_cache_bind_end_t cmpl, void *priv);
|
ocf_mngt_cache_bind_end_t cmpl, void *priv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Completion callback of cache activate operation
|
||||||
|
*
|
||||||
|
* @param[in] cache Cache handle
|
||||||
|
* @param[in] priv Callback context
|
||||||
|
* @param[in] error Error code (zero on success)
|
||||||
|
*/
|
||||||
|
typedef void (*ocf_mngt_cache_activate_end_t)(ocf_cache_t cache,
|
||||||
|
void *priv, int error);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Activate cache instance
|
||||||
|
*
|
||||||
|
* @param[in] cache Cache handle
|
||||||
|
* @param[in] cfg Caching device configuration
|
||||||
|
* @param[in] cmpl Completion callback
|
||||||
|
* @param[in] priv Completion callback context
|
||||||
|
*/
|
||||||
|
void ocf_mngt_cache_activate(ocf_cache_t cache,
|
||||||
|
struct ocf_mngt_cache_device_config *cfg,
|
||||||
|
ocf_mngt_cache_activate_end_t cmpl, void *priv);
|
||||||
|
|
||||||
/* Adding and removing cores */
|
/* Adding and removing cores */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,6 +95,8 @@ struct ocf_cache_attach_context {
|
|||||||
uint64_t volume_size;
|
uint64_t volume_size;
|
||||||
/*!< size of the device in cache lines */
|
/*!< size of the device in cache lines */
|
||||||
|
|
||||||
|
struct ocf_volume cache_volume;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief initialization state (in case of error, it is used to know
|
* @brief initialization state (in case of error, it is used to know
|
||||||
* which assets have to be deallocated in premature exit from function
|
* which assets have to be deallocated in premature exit from function
|
||||||
@ -103,6 +105,9 @@ struct ocf_cache_attach_context {
|
|||||||
bool device_alloc : 1;
|
bool device_alloc : 1;
|
||||||
/*!< data structure allocated */
|
/*!< data structure allocated */
|
||||||
|
|
||||||
|
bool volume_stored : 1;
|
||||||
|
/*!< underlying device volume is stored in contex */
|
||||||
|
|
||||||
bool volume_inited : 1;
|
bool volume_inited : 1;
|
||||||
/*!< underlying device volume is initialized */
|
/*!< underlying device volume is initialized */
|
||||||
|
|
||||||
@ -626,9 +631,6 @@ static void _ocf_mngt_load_init_instance_recovery(
|
|||||||
|
|
||||||
init_attached_data_structures_recovery(cache);
|
init_attached_data_structures_recovery(cache);
|
||||||
|
|
||||||
ocf_cache_log(cache, log_warn,
|
|
||||||
"ERROR: Cache device did not shut down properly!\n");
|
|
||||||
|
|
||||||
ocf_cache_log(cache, log_info, "Initiating recovery sequence...\n");
|
ocf_cache_log(cache, log_info, "Initiating recovery sequence...\n");
|
||||||
|
|
||||||
ocf_metadata_load_recovery(cache,
|
ocf_metadata_load_recovery(cache,
|
||||||
@ -639,11 +641,15 @@ static void _ocf_mngt_load_init_instance(ocf_pipeline_t pipeline,
|
|||||||
void *priv, ocf_pipeline_arg_t arg)
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
{
|
{
|
||||||
struct ocf_cache_attach_context *context = priv;
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
|
||||||
if (context->metadata.shutdown_status == ocf_metadata_clean_shutdown)
|
if (context->metadata.shutdown_status == ocf_metadata_clean_shutdown) {
|
||||||
_ocf_mngt_load_init_instance_clean_load(context);
|
_ocf_mngt_load_init_instance_clean_load(context);
|
||||||
else
|
} else {
|
||||||
|
ocf_cache_log(cache, log_warn,
|
||||||
|
"ERROR: Cache device did not shut down properly!\n");
|
||||||
_ocf_mngt_load_init_instance_recovery(context);
|
_ocf_mngt_load_init_instance_recovery(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1215,44 +1221,6 @@ static void _ocf_mngt_init_handle_error(ocf_ctx_t ctx,
|
|||||||
env_rmutex_unlock(&ctx->lock);
|
env_rmutex_unlock(&ctx->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_attach_handle_error(
|
|
||||||
struct ocf_cache_attach_context *context)
|
|
||||||
{
|
|
||||||
ocf_cache_t cache = context->cache;
|
|
||||||
|
|
||||||
if (context->flags.cleaner_started)
|
|
||||||
ocf_stop_cleaner(cache);
|
|
||||||
|
|
||||||
if (context->flags.promotion_initialized)
|
|
||||||
__deinit_promotion_policy(cache);
|
|
||||||
|
|
||||||
if (context->flags.cores_opened)
|
|
||||||
_ocf_mngt_close_all_uninitialized_cores(cache);
|
|
||||||
|
|
||||||
if (context->flags.attached_metadata_inited)
|
|
||||||
ocf_metadata_deinit_variable_size(cache);
|
|
||||||
|
|
||||||
if (context->flags.concurrency_inited)
|
|
||||||
ocf_concurrency_deinit(cache);
|
|
||||||
|
|
||||||
if (context->flags.volume_opened)
|
|
||||||
ocf_volume_close(&cache->device->volume);
|
|
||||||
|
|
||||||
if (context->flags.volume_inited)
|
|
||||||
ocf_volume_deinit(&cache->device->volume);
|
|
||||||
|
|
||||||
if (context->flags.front_volume_opened)
|
|
||||||
ocf_volume_close(&cache->device->front_volume);
|
|
||||||
|
|
||||||
if (context->flags.front_volume_inited)
|
|
||||||
ocf_volume_deinit(&cache->device->front_volume);
|
|
||||||
|
|
||||||
if (context->flags.device_alloc)
|
|
||||||
env_vfree(cache->device);
|
|
||||||
|
|
||||||
ocf_pipeline_destroy(cache->stop_pipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _ocf_mngt_cache_init(ocf_cache_t cache,
|
static void _ocf_mngt_cache_init(ocf_cache_t cache,
|
||||||
struct ocf_cache_mngt_init_params *params)
|
struct ocf_cache_mngt_init_params *params)
|
||||||
{
|
{
|
||||||
@ -1370,6 +1338,15 @@ static void _ocf_mngt_cache_set_passive(ocf_cache_t cache)
|
|||||||
env_bit_set(ocf_cache_state_passive, &cache->cache_state);
|
env_bit_set(ocf_cache_state_passive, &cache->cache_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_cache_set_active(ocf_cache_t cache)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Clear passive state and set the running bit.
|
||||||
|
*/
|
||||||
|
env_bit_clear(ocf_cache_state_passive, &cache->cache_state);
|
||||||
|
env_bit_set(ocf_cache_state_running, &cache->cache_state);
|
||||||
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_init_attached_nonpersistent(ocf_pipeline_t pipeline,
|
static void _ocf_mngt_init_attached_nonpersistent(ocf_pipeline_t pipeline,
|
||||||
void *priv, ocf_pipeline_arg_t arg)
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
{
|
{
|
||||||
@ -1634,6 +1611,46 @@ static void _ocf_mngt_attach_post_init(ocf_pipeline_t pipeline,
|
|||||||
ocf_pipeline_next(pipeline);
|
ocf_pipeline_next(pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_attach_handle_error(
|
||||||
|
struct ocf_cache_attach_context *context)
|
||||||
|
{
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
|
||||||
|
if (context->flags.cleaner_started)
|
||||||
|
ocf_stop_cleaner(cache);
|
||||||
|
|
||||||
|
if (context->flags.promotion_initialized)
|
||||||
|
__deinit_promotion_policy(cache);
|
||||||
|
|
||||||
|
if (context->flags.cores_opened)
|
||||||
|
_ocf_mngt_close_all_uninitialized_cores(cache);
|
||||||
|
|
||||||
|
if (context->flags.attached_metadata_inited)
|
||||||
|
ocf_metadata_deinit_variable_size(cache);
|
||||||
|
|
||||||
|
if (context->flags.concurrency_inited)
|
||||||
|
ocf_concurrency_deinit(cache);
|
||||||
|
|
||||||
|
if (context->flags.volume_opened)
|
||||||
|
ocf_volume_close(&cache->device->volume);
|
||||||
|
|
||||||
|
if (context->flags.volume_inited)
|
||||||
|
ocf_volume_deinit(&cache->device->volume);
|
||||||
|
|
||||||
|
if (context->flags.front_volume_opened)
|
||||||
|
ocf_volume_close(&cache->device->front_volume);
|
||||||
|
|
||||||
|
if (context->flags.front_volume_inited)
|
||||||
|
ocf_volume_deinit(&cache->device->front_volume);
|
||||||
|
|
||||||
|
if (context->flags.device_alloc) {
|
||||||
|
env_vfree(cache->device);
|
||||||
|
cache->device = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ocf_pipeline_destroy(cache->stop_pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_cache_attach_finish(ocf_pipeline_t pipeline,
|
static void _ocf_mngt_cache_attach_finish(ocf_pipeline_t pipeline,
|
||||||
void *priv, int error)
|
void *priv, int error)
|
||||||
{
|
{
|
||||||
@ -2038,6 +2055,241 @@ struct ocf_pipeline_properties _ocf_mngt_cache_bind_pipeline_properties = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void _ocf_mngt_activate_wait_metadata_io_finish(void *priv)
|
||||||
|
{
|
||||||
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
|
||||||
|
ocf_pipeline_next(context->pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_activate_wait_metadata_io(ocf_pipeline_t pipeline,
|
||||||
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
|
{
|
||||||
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
|
||||||
|
ocf_refcnt_freeze(&cache->refcnt.metadata);
|
||||||
|
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
|
||||||
|
_ocf_mngt_activate_wait_metadata_io_finish, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_activate_swap_cache_device(ocf_pipeline_t pipeline,
|
||||||
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
|
{
|
||||||
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
const struct ocf_volume_uuid *cache_uuid;
|
||||||
|
ocf_volume_type_t type;
|
||||||
|
int ret, cmp;
|
||||||
|
|
||||||
|
cache_uuid = ocf_volume_get_uuid(ocf_cache_get_volume(cache));
|
||||||
|
ret = env_memcmp(context->cfg.uuid.data, context->cfg.uuid.size,
|
||||||
|
cache_uuid->data, cache_uuid->size, &cmp);
|
||||||
|
if (ret)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, ret);
|
||||||
|
|
||||||
|
if (cmp == 0)
|
||||||
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
|
|
||||||
|
ret = ocf_volume_init(&context->cache_volume, 0, NULL, false);
|
||||||
|
if (!ret)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, ret);
|
||||||
|
|
||||||
|
ocf_volume_move(&context->cache_volume, &cache->device->volume);
|
||||||
|
context->flags.volume_stored = true;
|
||||||
|
|
||||||
|
type = ocf_ctx_get_volume_type(cache->owner, context->cfg.volume_type);
|
||||||
|
if (!type) {
|
||||||
|
OCF_PL_FINISH_RET(pipeline,
|
||||||
|
-OCF_ERR_INVAL_VOLUME_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ocf_volume_init(&cache->device->volume, type,
|
||||||
|
&context->cfg.uuid, true);
|
||||||
|
if (ret)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, ret);
|
||||||
|
|
||||||
|
cache->device->volume.cache = cache;
|
||||||
|
context->flags.volume_inited = true;
|
||||||
|
|
||||||
|
ret = ocf_volume_open(&cache->device->volume,
|
||||||
|
context->cfg.volume_params);
|
||||||
|
if (ret) {
|
||||||
|
ocf_cache_log(cache, log_err, "ERROR: Cache not available\n");
|
||||||
|
OCF_PL_FINISH_RET(pipeline, ret);
|
||||||
|
}
|
||||||
|
context->flags.volume_opened = true;
|
||||||
|
|
||||||
|
context->volume_size = ocf_volume_get_length(&cache->device->volume);
|
||||||
|
|
||||||
|
ocf_pipeline_next(pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_activate_check_superblock_complete(void *priv, int error)
|
||||||
|
{
|
||||||
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline, error);
|
||||||
|
|
||||||
|
result = ocf_metadata_validate_superblock(cache->owner,
|
||||||
|
cache->conf_meta);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline, result);
|
||||||
|
|
||||||
|
if (cache->conf_meta->metadata_layout != cache->metadata.layout) {
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline,
|
||||||
|
-OCF_ERR_METADATA_LAYOUT_MISMATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache->conf_meta->line_size != cache->metadata.settings.size) {
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline,
|
||||||
|
-OCF_ERR_CACHE_LINE_SIZE_MISMATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
ocf_pipeline_next(context->pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_activate_check_superblock(ocf_pipeline_t pipeline,
|
||||||
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
|
{
|
||||||
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
|
||||||
|
ocf_metadata_sb_crc_recovery(cache,
|
||||||
|
_ocf_mngt_activate_check_superblock_complete, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_activate_compare_superblock_end(
|
||||||
|
struct ocf_metadata_read_sb_ctx *sb_ctx)
|
||||||
|
{
|
||||||
|
struct ocf_superblock_config *superblock = &sb_ctx->superblock;
|
||||||
|
struct ocf_cache_attach_context *context = sb_ctx->priv1;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
int result, diff;
|
||||||
|
|
||||||
|
result = env_memcmp(cache->conf_meta, sizeof(*cache->conf_meta),
|
||||||
|
superblock, sizeof(*superblock), &diff);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline, result);
|
||||||
|
|
||||||
|
if (diff) {
|
||||||
|
ocf_cache_log(cache, log_err, "Superblock missmatch!\n");
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_INVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ocf_pipeline_next(context->pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_activate_compare_superblock(ocf_pipeline_t pipeline,
|
||||||
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
|
{
|
||||||
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = ocf_metadata_read_sb(cache->owner, ocf_cache_get_volume(cache),
|
||||||
|
_ocf_mngt_activate_compare_superblock_end,
|
||||||
|
context, NULL);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_activate_init_properties(ocf_pipeline_t pipeline,
|
||||||
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
|
{
|
||||||
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
|
||||||
|
OCF_ASSERT_PLUGGED(cache);
|
||||||
|
|
||||||
|
context->metadata.shutdown_status = ocf_metadata_dirty_shutdown;
|
||||||
|
context->metadata.dirty_flushed = DIRTY_NOT_FLUSHED;
|
||||||
|
context->metadata.line_size = context->cfg.cache_line_size;
|
||||||
|
|
||||||
|
ocf_pipeline_next(pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_activate_handle_error(
|
||||||
|
struct ocf_cache_attach_context *context)
|
||||||
|
{
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
|
||||||
|
if (context->flags.cleaner_started)
|
||||||
|
ocf_stop_cleaner(cache);
|
||||||
|
|
||||||
|
if (context->flags.promotion_initialized)
|
||||||
|
__deinit_promotion_policy(cache);
|
||||||
|
|
||||||
|
if (context->flags.cores_opened)
|
||||||
|
_ocf_mngt_close_all_uninitialized_cores(cache);
|
||||||
|
|
||||||
|
if (context->flags.volume_opened)
|
||||||
|
ocf_volume_close(&cache->device->volume);
|
||||||
|
|
||||||
|
if (context->flags.volume_inited)
|
||||||
|
ocf_volume_deinit(&cache->device->volume);
|
||||||
|
|
||||||
|
if (context->flags.volume_stored)
|
||||||
|
ocf_volume_move(&cache->device->volume, &context->cache_volume);
|
||||||
|
|
||||||
|
ocf_refcnt_unfreeze(&cache->refcnt.metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_cache_activate_finish(ocf_pipeline_t pipeline,
|
||||||
|
void *priv, int error)
|
||||||
|
{
|
||||||
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
ocf_pipeline_t stop_pipeline;
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
_ocf_mngt_activate_handle_error(context);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ocf_pipeline_create(&stop_pipeline, cache,
|
||||||
|
&ocf_mngt_cache_stop_pipeline_properties);
|
||||||
|
if (error) {
|
||||||
|
_ocf_mngt_activate_handle_error(context);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ocf_pipeline_destroy(cache->stop_pipeline);
|
||||||
|
cache->stop_pipeline = stop_pipeline;
|
||||||
|
|
||||||
|
ocf_volume_deinit(&context->cache_volume);
|
||||||
|
|
||||||
|
out:
|
||||||
|
context->cmpl(context->cache, context->priv1, context->priv2, error);
|
||||||
|
|
||||||
|
env_vfree(context->cfg.uuid.data);
|
||||||
|
ocf_pipeline_destroy(context->pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ocf_pipeline_properties _ocf_mngt_cache_activate_pipeline_properties = {
|
||||||
|
.priv_size = sizeof(struct ocf_cache_attach_context),
|
||||||
|
.finish = _ocf_mngt_cache_activate_finish,
|
||||||
|
.steps = {
|
||||||
|
OCF_PL_STEP(_ocf_mngt_copy_uuid_data),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_activate_wait_metadata_io),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_activate_swap_cache_device),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_activate_check_superblock),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_activate_compare_superblock),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_activate_init_properties),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_test_volume),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_init_cleaner),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_init_promotion),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_load_add_cores),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_load_post_metadata_load),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_attach_shutdown_status),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_attach_post_init),
|
||||||
|
OCF_PL_STEP_TERMINATOR(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static void _ocf_mngt_cache_attach(ocf_cache_t cache,
|
static void _ocf_mngt_cache_attach(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_device_config *cfg,
|
||||||
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
||||||
@ -2149,6 +2401,35 @@ static void _ocf_mngt_cache_bind(ocf_cache_t cache,
|
|||||||
OCF_PL_NEXT_RET(pipeline);
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_cache_activate(ocf_cache_t cache,
|
||||||
|
struct ocf_mngt_cache_device_config *cfg,
|
||||||
|
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
||||||
|
{
|
||||||
|
struct ocf_cache_attach_context *context;
|
||||||
|
ocf_pipeline_t pipeline;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (!ocf_cache_is_passive(cache))
|
||||||
|
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_CACHE_EXIST);
|
||||||
|
|
||||||
|
result = ocf_pipeline_create(&pipeline, cache,
|
||||||
|
&_ocf_mngt_cache_activate_pipeline_properties);
|
||||||
|
if (result)
|
||||||
|
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_NO_MEM);
|
||||||
|
|
||||||
|
context = ocf_pipeline_get_priv(pipeline);
|
||||||
|
|
||||||
|
context->cmpl = cmpl;
|
||||||
|
context->priv1 = priv1;
|
||||||
|
context->priv2 = priv2;
|
||||||
|
context->pipeline = pipeline;
|
||||||
|
|
||||||
|
context->cache = cache;
|
||||||
|
context->cfg = *cfg;
|
||||||
|
|
||||||
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
static int _ocf_mngt_cache_validate_cfg(struct ocf_mngt_cache_config *cfg)
|
static int _ocf_mngt_cache_validate_cfg(struct ocf_mngt_cache_config *cfg)
|
||||||
{
|
{
|
||||||
if (!strnlen(cfg->name, OCF_CACHE_NAME_SIZE))
|
if (!strnlen(cfg->name, OCF_CACHE_NAME_SIZE))
|
||||||
@ -2444,6 +2725,51 @@ void ocf_mngt_cache_bind(ocf_cache_t cache,
|
|||||||
cmpl, priv);
|
cmpl, priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_cache_activate_complete(ocf_cache_t cache, void *priv1,
|
||||||
|
void *priv2, int error)
|
||||||
|
{
|
||||||
|
ocf_mngt_cache_bind_end_t cmpl = priv1;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
OCF_CMPL_RET(cache, priv2, error);
|
||||||
|
|
||||||
|
_ocf_mngt_cache_set_active(cache);
|
||||||
|
ocf_cache_log(cache, log_info, "Successfully activated\n");
|
||||||
|
|
||||||
|
OCF_CMPL_RET(cache, priv2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ocf_mngt_cache_activate(ocf_cache_t cache,
|
||||||
|
struct ocf_mngt_cache_device_config *cfg,
|
||||||
|
ocf_mngt_cache_activate_end_t cmpl, void *priv)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
OCF_CHECK_NULL(cache);
|
||||||
|
OCF_CHECK_NULL(cfg);
|
||||||
|
|
||||||
|
if (!cache->mngt_queue)
|
||||||
|
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
||||||
|
|
||||||
|
/* Activate is not allowed in volatile metadata mode */
|
||||||
|
if (cache->metadata.is_volatile)
|
||||||
|
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
||||||
|
|
||||||
|
/* Activate is not allowed with 'force' flag on */
|
||||||
|
if (cfg->force) {
|
||||||
|
ocf_cache_log(cache, log_err, "Using 'force' flag is forbidden "
|
||||||
|
"for activate operation.");
|
||||||
|
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = _ocf_mngt_cache_validate_device_cfg(cfg);
|
||||||
|
if (result)
|
||||||
|
OCF_CMPL_RET(cache, priv, result);
|
||||||
|
|
||||||
|
_ocf_mngt_cache_activate(cache, cfg, _ocf_mngt_cache_activate_complete,
|
||||||
|
cmpl, priv);
|
||||||
|
}
|
||||||
|
|
||||||
static void ocf_mngt_cache_stop_detached(ocf_cache_t cache,
|
static void ocf_mngt_cache_stop_detached(ocf_cache_t cache,
|
||||||
ocf_mngt_cache_stop_end_t cmpl, void *priv)
|
ocf_mngt_cache_stop_end_t cmpl, void *priv)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user