commit
7b120162a5
@ -94,7 +94,7 @@ static void simple_complete(ocf_cache_t cache, void *priv, int error)
|
|||||||
int initialize_cache(ocf_ctx_t ctx, ocf_cache_t *cache)
|
int initialize_cache(ocf_ctx_t ctx, ocf_cache_t *cache)
|
||||||
{
|
{
|
||||||
struct ocf_mngt_cache_config cache_cfg = { .name = "cache1" };
|
struct ocf_mngt_cache_config cache_cfg = { .name = "cache1" };
|
||||||
struct ocf_mngt_cache_device_config device_cfg = { };
|
struct ocf_mngt_cache_attach_config attach_cfg = { };
|
||||||
struct cache_priv *cache_priv;
|
struct cache_priv *cache_priv;
|
||||||
struct simple_context context;
|
struct simple_context context;
|
||||||
int ret;
|
int ret;
|
||||||
@ -110,9 +110,9 @@ int initialize_cache(ocf_ctx_t ctx, ocf_cache_t *cache)
|
|||||||
cache_cfg.metadata_volatile = true;
|
cache_cfg.metadata_volatile = true;
|
||||||
|
|
||||||
/* Cache deivce (volume) configuration */
|
/* Cache deivce (volume) configuration */
|
||||||
ocf_mngt_cache_device_config_set_default(&device_cfg);
|
ocf_mngt_cache_attach_config_set_default(&attach_cfg);
|
||||||
device_cfg.volume_type = VOL_TYPE;
|
attach_cfg.device.volume_type = VOL_TYPE;
|
||||||
ret = ocf_uuid_set_str(&device_cfg.uuid, "cache");
|
ret = ocf_uuid_set_str(&attach_cfg.device.uuid, "cache");
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ int initialize_cache(ocf_ctx_t ctx, ocf_cache_t *cache)
|
|||||||
goto err_cache;
|
goto err_cache;
|
||||||
|
|
||||||
/* Attach volume to cache */
|
/* Attach volume to cache */
|
||||||
ocf_mngt_cache_attach(*cache, &device_cfg, simple_complete, &context);
|
ocf_mngt_cache_attach(*cache, &attach_cfg, simple_complete, &context);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_cache;
|
goto err_cache;
|
||||||
|
|
||||||
|
@ -92,6 +92,9 @@ struct ocf_cache_info {
|
|||||||
|
|
||||||
uint32_t metadata_end_offset;
|
uint32_t metadata_end_offset;
|
||||||
/*!< LBA offset where metadata ends (in 4KiB blocks) */
|
/*!< LBA offset where metadata ends (in 4KiB blocks) */
|
||||||
|
|
||||||
|
bool failover_detached;
|
||||||
|
/*!< true if cache drive detached for failover */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -159,7 +162,7 @@ bool ocf_cache_is_running(ocf_cache_t cache);
|
|||||||
* @retval 1 Caching device is in passive state
|
* @retval 1 Caching device is in passive state
|
||||||
* @retval 0 Caching device is not in passive state
|
* @retval 0 Caching device is not in passive state
|
||||||
*/
|
*/
|
||||||
bool ocf_cache_is_passive(ocf_cache_t cache);
|
bool ocf_cache_is_standby(ocf_cache_t cache);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get cache mode of given cache object
|
* @brief Get cache mode of given cache object
|
||||||
|
@ -124,8 +124,8 @@ typedef enum {
|
|||||||
ocf_cache_state_incomplete = 3, //!< ocf_cache_state_incomplete
|
ocf_cache_state_incomplete = 3, //!< ocf_cache_state_incomplete
|
||||||
/*!< OCF cache has at least one inactive core */
|
/*!< OCF cache has at least one inactive core */
|
||||||
|
|
||||||
ocf_cache_state_passive = 4, //!< ocf_cache_state_passive
|
ocf_cache_state_standby = 4, //!< ocf_cache_state_standby
|
||||||
/*!< OCF is currently in passive mode */
|
/*!< OCF is currently in standby mode */
|
||||||
|
|
||||||
ocf_cache_state_max //!< ocf_cache_state_max
|
ocf_cache_state_max //!< ocf_cache_state_max
|
||||||
/*!< Stopper of cache state enumerator */
|
/*!< Stopper of cache state enumerator */
|
||||||
|
@ -359,7 +359,7 @@ void ocf_mngt_cache_stop(ocf_cache_t cache,
|
|||||||
ocf_mngt_cache_stop_end_t cmpl, void *priv);
|
ocf_mngt_cache_stop_end_t cmpl, void *priv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Cache attach configuration
|
* @brief Caching device configuration
|
||||||
*/
|
*/
|
||||||
struct ocf_mngt_cache_device_config {
|
struct ocf_mngt_cache_device_config {
|
||||||
/**
|
/**
|
||||||
@ -367,16 +367,38 @@ struct ocf_mngt_cache_device_config {
|
|||||||
*/
|
*/
|
||||||
struct ocf_volume_uuid uuid;
|
struct ocf_volume_uuid uuid;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Cache line size
|
|
||||||
*/
|
|
||||||
ocf_cache_line_size_t cache_line_size;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Cache volume type
|
* @brief Cache volume type
|
||||||
*/
|
*/
|
||||||
uint8_t volume_type;
|
uint8_t volume_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief If set, cache features (like discard) are tested
|
||||||
|
* before starting cache
|
||||||
|
*/
|
||||||
|
bool perform_test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Optional opaque volume parameters, passed down to cache volume
|
||||||
|
* open callback
|
||||||
|
*/
|
||||||
|
void *volume_params;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Cache attach configuration
|
||||||
|
*/
|
||||||
|
struct ocf_mngt_cache_attach_config {
|
||||||
|
/**
|
||||||
|
* @brief Cache device configuration - must be the first field
|
||||||
|
*/
|
||||||
|
struct ocf_mngt_cache_device_config device;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Cache line size
|
||||||
|
*/
|
||||||
|
ocf_cache_line_size_t cache_line_size;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Automatically open core volumes when loading cache
|
* @brief Automatically open core volumes when loading cache
|
||||||
*
|
*
|
||||||
@ -400,22 +422,10 @@ struct ocf_mngt_cache_device_config {
|
|||||||
*/
|
*/
|
||||||
bool force;
|
bool force;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief If set, cache features (like discard) are tested
|
|
||||||
* before starting cache
|
|
||||||
*/
|
|
||||||
bool perform_test;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief If set, cache device will be discarded on cache start
|
* @brief If set, cache device will be discarded on cache start
|
||||||
*/
|
*/
|
||||||
bool discard_on_start;
|
bool discard_on_start;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Optional opaque volume parameters, passed down to cache volume
|
|
||||||
* open callback
|
|
||||||
*/
|
|
||||||
void *volume_params;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -426,15 +436,15 @@ struct ocf_mngt_cache_device_config {
|
|||||||
*
|
*
|
||||||
* @param[in] cfg Cache device config stucture
|
* @param[in] cfg Cache device config stucture
|
||||||
*/
|
*/
|
||||||
static inline void ocf_mngt_cache_device_config_set_default(
|
static inline void ocf_mngt_cache_attach_config_set_default(
|
||||||
struct ocf_mngt_cache_device_config *cfg)
|
struct ocf_mngt_cache_attach_config *cfg)
|
||||||
{
|
{
|
||||||
cfg->cache_line_size = ocf_cache_line_size_none;
|
cfg->cache_line_size = ocf_cache_line_size_none;
|
||||||
cfg->open_cores = true;
|
cfg->open_cores = true;
|
||||||
cfg->force = false;
|
cfg->force = false;
|
||||||
cfg->perform_test = true;
|
|
||||||
cfg->discard_on_start = true;
|
cfg->discard_on_start = true;
|
||||||
cfg->volume_params = NULL;
|
cfg->device.perform_test = true;
|
||||||
|
cfg->device.volume_params = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -469,7 +479,7 @@ typedef void (*ocf_mngt_cache_attach_end_t)(ocf_cache_t cache,
|
|||||||
* @param[in] priv Completion callback context
|
* @param[in] priv Completion callback context
|
||||||
*/
|
*/
|
||||||
void ocf_mngt_cache_attach(ocf_cache_t cache,
|
void ocf_mngt_cache_attach(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_attach_config *cfg,
|
||||||
ocf_mngt_cache_attach_end_t cmpl, void *priv);
|
ocf_mngt_cache_attach_end_t cmpl, void *priv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -511,7 +521,7 @@ typedef void (*ocf_mngt_cache_load_end_t)(ocf_cache_t cache,
|
|||||||
* @param[in] priv Completion callback context
|
* @param[in] priv Completion callback context
|
||||||
*/
|
*/
|
||||||
void ocf_mngt_cache_load(ocf_cache_t cache,
|
void ocf_mngt_cache_load(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_attach_config *cfg,
|
||||||
ocf_mngt_cache_load_end_t cmpl, void *priv);
|
ocf_mngt_cache_load_end_t cmpl, void *priv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -525,17 +535,21 @@ typedef void (*ocf_mngt_cache_bind_end_t)(ocf_cache_t cache,
|
|||||||
void *priv, int error);
|
void *priv, int error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Bind cache instance
|
* @brief Initiate failover standby
|
||||||
*
|
*
|
||||||
* @param[in] cache Cache handle
|
* @param[in] cache Cache handle
|
||||||
* @param[in] cfg Caching device configuration
|
* @param[in] cfg Caching device configuration
|
||||||
* @param[in] cmpl Completion callback
|
* @param[in] cmpl Completion callback
|
||||||
* @param[in] priv Completion callback context
|
* @param[in] priv Completion callback context
|
||||||
*/
|
*/
|
||||||
void ocf_mngt_cache_bind(ocf_cache_t cache,
|
void ocf_mngt_cache_standby(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_attach_config *cfg,
|
||||||
ocf_mngt_cache_bind_end_t cmpl, void *priv);
|
ocf_mngt_cache_bind_end_t cmpl, void *priv);
|
||||||
|
|
||||||
|
typedef void (*ocf_mngt_cache_failover_detach_end_t)(void *priv, int error);
|
||||||
|
|
||||||
|
void ocf_mngt_cache_failover_detach(ocf_cache_t cache,
|
||||||
|
ocf_mngt_cache_failover_detach_end_t cmpl, void *priv);
|
||||||
/**
|
/**
|
||||||
* @brief Completion callback of cache activate operation
|
* @brief Completion callback of cache activate operation
|
||||||
*
|
*
|
||||||
|
@ -87,10 +87,11 @@ typedef void (*_ocf_mngt_cache_attach_end_t)(ocf_cache_t, void *priv1,
|
|||||||
void *priv2, int error);
|
void *priv2, int error);
|
||||||
|
|
||||||
struct ocf_cache_attach_context {
|
struct ocf_cache_attach_context {
|
||||||
|
struct ocf_mngt_cache_attach_config cfg;
|
||||||
|
|
||||||
ocf_cache_t cache;
|
ocf_cache_t cache;
|
||||||
/*!< cache that is being initialized */
|
/*!< cache that is being initialized */
|
||||||
|
|
||||||
struct ocf_mngt_cache_device_config cfg;
|
|
||||||
|
|
||||||
uint64_t volume_size;
|
uint64_t volume_size;
|
||||||
/*!< size of the device in cache lines */
|
/*!< size of the device in cache lines */
|
||||||
@ -134,6 +135,14 @@ struct ocf_cache_attach_context {
|
|||||||
* load or recovery
|
* load or recovery
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool uuid_copied : 1;
|
||||||
|
/*!< copied uuid data to context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool metadata_frozen : 1;
|
||||||
|
/*!< metadata reference counter frozen
|
||||||
|
*/
|
||||||
|
|
||||||
bool concurrency_inited : 1;
|
bool concurrency_inited : 1;
|
||||||
} flags;
|
} flags;
|
||||||
|
|
||||||
@ -690,6 +699,7 @@ static void _ocf_mngt_attach_cache_device(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;
|
||||||
|
struct ocf_mngt_cache_device_config *device_cfg = &context->cfg.device;
|
||||||
ocf_cache_t cache = context->cache;
|
ocf_cache_t cache = context->cache;
|
||||||
ocf_volume_type_t type;
|
ocf_volume_type_t type;
|
||||||
int ret;
|
int ret;
|
||||||
@ -701,14 +711,14 @@ static void _ocf_mngt_attach_cache_device(ocf_pipeline_t pipeline,
|
|||||||
context->flags.device_alloc = true;
|
context->flags.device_alloc = true;
|
||||||
|
|
||||||
/* Prepare UUID of cache volume */
|
/* Prepare UUID of cache volume */
|
||||||
type = ocf_ctx_get_volume_type(cache->owner, context->cfg.volume_type);
|
type = ocf_ctx_get_volume_type(cache->owner, device_cfg->volume_type);
|
||||||
if (!type) {
|
if (!type) {
|
||||||
OCF_PL_FINISH_RET(pipeline,
|
OCF_PL_FINISH_RET(pipeline,
|
||||||
-OCF_ERR_INVAL_VOLUME_TYPE);
|
-OCF_ERR_INVAL_VOLUME_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ocf_volume_init(&cache->device->volume, type,
|
ret = ocf_volume_init(&cache->device->volume, type,
|
||||||
&context->cfg.uuid, true);
|
&device_cfg->uuid, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
OCF_PL_FINISH_RET(pipeline, ret);
|
OCF_PL_FINISH_RET(pipeline, ret);
|
||||||
|
|
||||||
@ -720,7 +730,7 @@ static void _ocf_mngt_attach_cache_device(ocf_pipeline_t pipeline,
|
|||||||
* need to know size of cache device.
|
* need to know size of cache device.
|
||||||
*/
|
*/
|
||||||
ret = ocf_volume_open(&cache->device->volume,
|
ret = ocf_volume_open(&cache->device->volume,
|
||||||
context->cfg.volume_params);
|
device_cfg->volume_params);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ocf_cache_log(cache, log_err, "ERROR: Cache not available\n");
|
ocf_cache_log(cache, log_err, "ERROR: Cache not available\n");
|
||||||
OCF_PL_FINISH_RET(pipeline, ret);
|
OCF_PL_FINISH_RET(pipeline, ret);
|
||||||
@ -943,13 +953,14 @@ static void _ocf_mngt_test_volume(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;
|
||||||
|
struct ocf_mngt_cache_device_config *device_cfg = &context->cfg.device;
|
||||||
ocf_cache_t cache = context->cache;
|
ocf_cache_t cache = context->cache;
|
||||||
ocf_pipeline_t test_pipeline;
|
ocf_pipeline_t test_pipeline;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
cache->device->volume.features.discard_zeroes = 1;
|
cache->device->volume.features.discard_zeroes = 1;
|
||||||
|
|
||||||
if (!context->cfg.perform_test)
|
if (!device_cfg->perform_test)
|
||||||
OCF_PL_NEXT_RET(pipeline);
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
|
|
||||||
context->test.reserved_lba_addr = ocf_metadata_get_reserved_lba(cache);
|
context->test.reserved_lba_addr = ocf_metadata_get_reserved_lba(cache);
|
||||||
@ -1154,8 +1165,7 @@ int ocf_mngt_get_ram_needed(ocf_cache_t cache,
|
|||||||
if (!type)
|
if (!type)
|
||||||
return -OCF_ERR_INVAL_VOLUME_TYPE;
|
return -OCF_ERR_INVAL_VOLUME_TYPE;
|
||||||
|
|
||||||
result = ocf_volume_create(&volume, type,
|
result = ocf_volume_create(&volume, type, &cfg->uuid);
|
||||||
&cfg->uuid);
|
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -1319,15 +1329,15 @@ static void _ocf_mngt_cache_set_passive(ocf_cache_t cache)
|
|||||||
* Clear initialization state and set the passive bit.
|
* Clear initialization state and set the passive bit.
|
||||||
*/
|
*/
|
||||||
env_bit_clear(ocf_cache_state_initializing, &cache->cache_state);
|
env_bit_clear(ocf_cache_state_initializing, &cache->cache_state);
|
||||||
env_bit_set(ocf_cache_state_passive, &cache->cache_state);
|
env_bit_set(ocf_cache_state_standby, &cache->cache_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_cache_set_active(ocf_cache_t cache)
|
static void _ocf_mngt_cache_set_active(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Clear passive state and set the running bit.
|
* Clear standby state and set the running bit.
|
||||||
*/
|
*/
|
||||||
env_bit_clear(ocf_cache_state_passive, &cache->cache_state);
|
env_bit_clear(ocf_cache_state_standby, &cache->cache_state);
|
||||||
env_bit_set(ocf_cache_state_running, &cache->cache_state);
|
env_bit_set(ocf_cache_state_running, &cache->cache_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1346,22 +1356,26 @@ static void _ocf_mngt_copy_uuid_data(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;
|
||||||
struct ocf_mngt_cache_device_config *cfg = &context->cfg;
|
struct ocf_mngt_cache_device_config *device_cfg = &context->cfg.device;
|
||||||
void *data;
|
void *data;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
data = env_vmalloc(cfg->uuid.size);
|
if (device_cfg->uuid.size == 0)
|
||||||
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
|
|
||||||
|
data = env_vmalloc(device_cfg->uuid.size);
|
||||||
if (!data)
|
if (!data)
|
||||||
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_NO_MEM);
|
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_NO_MEM);
|
||||||
|
|
||||||
result = env_memcpy(data, cfg->uuid.size, cfg->uuid.data,
|
result = env_memcpy(data, device_cfg->uuid.size, device_cfg->uuid.data,
|
||||||
cfg->uuid.size);
|
device_cfg->uuid.size);
|
||||||
if (result) {
|
if (result) {
|
||||||
env_vfree(data);
|
env_vfree(data);
|
||||||
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL);
|
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
context->cfg.uuid.data = data;
|
device_cfg->uuid.data = data;
|
||||||
|
context->flags.uuid_copied = true;
|
||||||
|
|
||||||
ocf_pipeline_next(pipeline);
|
ocf_pipeline_next(pipeline);
|
||||||
}
|
}
|
||||||
@ -1639,13 +1653,16 @@ static void _ocf_mngt_cache_attach_finish(ocf_pipeline_t pipeline,
|
|||||||
void *priv, int error)
|
void *priv, int error)
|
||||||
{
|
{
|
||||||
struct ocf_cache_attach_context *context = priv;
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
struct ocf_mngt_cache_device_config *device_cfg = &context->cfg.device;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
_ocf_mngt_attach_handle_error(context);
|
_ocf_mngt_attach_handle_error(context);
|
||||||
|
|
||||||
context->cmpl(context->cache, context->priv1, context->priv2, error);
|
context->cmpl(context->cache, context->priv1, context->priv2, error);
|
||||||
|
|
||||||
env_vfree(context->cfg.uuid.data);
|
if (context->flags.uuid_copied)
|
||||||
|
env_vfree(device_cfg->uuid.data);
|
||||||
|
|
||||||
ocf_pipeline_destroy(context->pipeline);
|
ocf_pipeline_destroy(context->pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2020,7 +2037,7 @@ static void _ocf_mngt_bind_post_init(ocf_pipeline_t pipeline,
|
|||||||
ocf_pipeline_next(pipeline);
|
ocf_pipeline_next(pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ocf_pipeline_properties _ocf_mngt_cache_bind_pipeline_properties = {
|
struct ocf_pipeline_properties _ocf_mngt_cache_standby_pipeline_properties = {
|
||||||
.priv_size = sizeof(struct ocf_cache_attach_context),
|
.priv_size = sizeof(struct ocf_cache_attach_context),
|
||||||
.finish = _ocf_mngt_cache_attach_finish,
|
.finish = _ocf_mngt_cache_attach_finish,
|
||||||
.steps = {
|
.steps = {
|
||||||
@ -2039,57 +2056,78 @@ struct ocf_pipeline_properties _ocf_mngt_cache_bind_pipeline_properties = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void _ocf_mngt_activate_wait_metadata_io_finish(void *priv)
|
struct ocf_cache_failover_detach_context {
|
||||||
|
ocf_pipeline_t pipeline;
|
||||||
|
ocf_cache_t cache;
|
||||||
|
ocf_mngt_cache_failover_detach_end_t cmpl;
|
||||||
|
void *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void _ocf_mngt_failover_detach_wait_metadata_io_finish(void *priv)
|
||||||
{
|
{
|
||||||
struct ocf_cache_attach_context *context = priv;
|
struct ocf_cache_failover_detach_context *context = priv;
|
||||||
|
|
||||||
ocf_pipeline_next(context->pipeline);
|
ocf_pipeline_next(context->pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_activate_wait_metadata_io(ocf_pipeline_t pipeline,
|
static void _ocf_mngt_failover_detach_wait_metadata_io(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_failover_detach_context *context = priv;
|
||||||
ocf_cache_t cache = context->cache;
|
ocf_cache_t cache = context->cache;
|
||||||
|
|
||||||
ocf_refcnt_freeze(&cache->refcnt.metadata);
|
ocf_refcnt_freeze(&cache->refcnt.metadata);
|
||||||
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
|
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
|
||||||
_ocf_mngt_activate_wait_metadata_io_finish, context);
|
_ocf_mngt_failover_detach_wait_metadata_io_finish, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_activate_swap_cache_device(ocf_pipeline_t pipeline,
|
static void _ocf_mngt_activate_swap_cache_device(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;
|
struct ocf_mngt_cache_device_config *device_cfg = &context->cfg.device;
|
||||||
const struct ocf_volume_uuid *cache_uuid;
|
const struct ocf_volume_uuid *cache_uuid;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
ocf_volume_t cache_volume = ocf_cache_get_volume(cache);
|
||||||
ocf_volume_type_t type;
|
ocf_volume_type_t type;
|
||||||
int ret, cmp;
|
int ret, cmp;
|
||||||
|
|
||||||
cache_uuid = ocf_volume_get_uuid(ocf_cache_get_volume(cache));
|
if (device_cfg->uuid.size == 0) {
|
||||||
ret = env_memcmp(context->cfg.uuid.data, context->cfg.uuid.size,
|
if (cache_volume->opened)
|
||||||
cache_uuid->data, cache_uuid->size, &cmp);
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
if (ret)
|
else
|
||||||
OCF_PL_FINISH_RET(pipeline, ret);
|
OCF_PL_FINISH_RET(pipeline, -EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
if (cmp == 0)
|
if (cache_volume->opened) {
|
||||||
OCF_PL_NEXT_RET(pipeline);
|
/* if uuid does not change then skip this step */
|
||||||
|
cache_uuid = ocf_volume_get_uuid(cache_volume);
|
||||||
|
ret = env_memcmp(device_cfg->uuid.data, device_cfg->uuid.size,
|
||||||
|
cache_uuid->data, cache_uuid->size, &cmp);
|
||||||
|
if (ret)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, ret);
|
||||||
|
|
||||||
ret = ocf_volume_init(&context->cache_volume, 0, NULL, false);
|
if (cmp == 0)
|
||||||
if (!ret)
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
OCF_PL_FINISH_RET(pipeline, ret);
|
|
||||||
|
|
||||||
ocf_volume_move(&context->cache_volume, &cache->device->volume);
|
/* move cache volume to the context */
|
||||||
context->flags.volume_stored = true;
|
ret = ocf_volume_init(&context->cache_volume,
|
||||||
|
cache_volume->type, NULL, false);
|
||||||
|
if (ret)
|
||||||
|
OCF_PL_FINISH_RET(pipeline, ret);
|
||||||
|
|
||||||
type = ocf_ctx_get_volume_type(cache->owner, context->cfg.volume_type);
|
ocf_volume_move(&context->cache_volume, &cache->device->volume);
|
||||||
|
context->flags.volume_stored = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = ocf_ctx_get_volume_type(cache->owner, device_cfg->volume_type);
|
||||||
if (!type) {
|
if (!type) {
|
||||||
OCF_PL_FINISH_RET(pipeline,
|
OCF_PL_FINISH_RET(pipeline,
|
||||||
-OCF_ERR_INVAL_VOLUME_TYPE);
|
-OCF_ERR_INVAL_VOLUME_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ocf_volume_init(&cache->device->volume, type,
|
ret = ocf_volume_init(&cache->device->volume, type,
|
||||||
&context->cfg.uuid, true);
|
&device_cfg->uuid, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
OCF_PL_FINISH_RET(pipeline, ret);
|
OCF_PL_FINISH_RET(pipeline, ret);
|
||||||
|
|
||||||
@ -2097,7 +2135,7 @@ static void _ocf_mngt_activate_swap_cache_device(ocf_pipeline_t pipeline,
|
|||||||
context->flags.volume_inited = true;
|
context->flags.volume_inited = true;
|
||||||
|
|
||||||
ret = ocf_volume_open(&cache->device->volume,
|
ret = ocf_volume_open(&cache->device->volume,
|
||||||
context->cfg.volume_params);
|
device_cfg->volume_params);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ocf_cache_log(cache, log_err, "ERROR: Cache not available\n");
|
ocf_cache_log(cache, log_err, "ERROR: Cache not available\n");
|
||||||
OCF_PL_FINISH_RET(pipeline, ret);
|
OCF_PL_FINISH_RET(pipeline, ret);
|
||||||
@ -2219,13 +2257,15 @@ static void _ocf_mngt_activate_handle_error(
|
|||||||
if (context->flags.volume_stored)
|
if (context->flags.volume_stored)
|
||||||
ocf_volume_move(&cache->device->volume, &context->cache_volume);
|
ocf_volume_move(&cache->device->volume, &context->cache_volume);
|
||||||
|
|
||||||
ocf_refcnt_unfreeze(&cache->refcnt.metadata);
|
if (context->flags.metadata_frozen)
|
||||||
|
ocf_refcnt_unfreeze(&cache->refcnt.metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_cache_activate_finish(ocf_pipeline_t pipeline,
|
static void _ocf_mngt_cache_activate_finish(ocf_pipeline_t pipeline,
|
||||||
void *priv, int error)
|
void *priv, int error)
|
||||||
{
|
{
|
||||||
struct ocf_cache_attach_context *context = priv;
|
struct ocf_cache_attach_context *context = priv;
|
||||||
|
struct ocf_mngt_cache_device_config *device_cfg = &context->cfg.device;
|
||||||
ocf_cache_t cache = context->cache;
|
ocf_cache_t cache = context->cache;
|
||||||
ocf_pipeline_t stop_pipeline;
|
ocf_pipeline_t stop_pipeline;
|
||||||
|
|
||||||
@ -2244,12 +2284,18 @@ static void _ocf_mngt_cache_activate_finish(ocf_pipeline_t pipeline,
|
|||||||
ocf_pipeline_destroy(cache->stop_pipeline);
|
ocf_pipeline_destroy(cache->stop_pipeline);
|
||||||
cache->stop_pipeline = stop_pipeline;
|
cache->stop_pipeline = stop_pipeline;
|
||||||
|
|
||||||
ocf_volume_deinit(&context->cache_volume);
|
if (context->flags.volume_stored) {
|
||||||
|
if (context->cache_volume.opened)
|
||||||
|
ocf_volume_close(&context->cache_volume);
|
||||||
|
ocf_volume_deinit(&context->cache_volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
context->cmpl(context->cache, context->priv1, context->priv2, error);
|
context->cmpl(context->cache, context->priv1, context->priv2, error);
|
||||||
|
|
||||||
env_vfree(context->cfg.uuid.data);
|
if (context->flags.uuid_copied)
|
||||||
|
env_vfree(device_cfg->uuid.data);
|
||||||
ocf_pipeline_destroy(context->pipeline);
|
ocf_pipeline_destroy(context->pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2258,7 +2304,6 @@ struct ocf_pipeline_properties _ocf_mngt_cache_activate_pipeline_properties = {
|
|||||||
.finish = _ocf_mngt_cache_activate_finish,
|
.finish = _ocf_mngt_cache_activate_finish,
|
||||||
.steps = {
|
.steps = {
|
||||||
OCF_PL_STEP(_ocf_mngt_copy_uuid_data),
|
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_swap_cache_device),
|
||||||
OCF_PL_STEP(_ocf_mngt_activate_check_superblock),
|
OCF_PL_STEP(_ocf_mngt_activate_check_superblock),
|
||||||
OCF_PL_STEP(_ocf_mngt_activate_compare_superblock),
|
OCF_PL_STEP(_ocf_mngt_activate_compare_superblock),
|
||||||
@ -2275,7 +2320,7 @@ struct ocf_pipeline_properties _ocf_mngt_cache_activate_pipeline_properties = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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_attach_config *cfg,
|
||||||
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
||||||
{
|
{
|
||||||
struct ocf_cache_attach_context *context;
|
struct ocf_cache_attach_context *context;
|
||||||
@ -2308,7 +2353,7 @@ static void _ocf_mngt_cache_attach(ocf_cache_t cache,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_cache_load(ocf_cache_t cache,
|
static void _ocf_mngt_cache_load(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_attach_config *cfg,
|
||||||
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
||||||
{
|
{
|
||||||
struct ocf_cache_attach_context *context;
|
struct ocf_cache_attach_context *context;
|
||||||
@ -2352,8 +2397,8 @@ ocf_mngt_cache_stop_passive_pipeline_properties = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void _ocf_mngt_cache_bind(ocf_cache_t cache,
|
static void _ocf_mngt_cache_standby(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_attach_config *cfg,
|
||||||
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
||||||
{
|
{
|
||||||
struct ocf_cache_attach_context *context;
|
struct ocf_cache_attach_context *context;
|
||||||
@ -2361,7 +2406,7 @@ static void _ocf_mngt_cache_bind(ocf_cache_t cache,
|
|||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = ocf_pipeline_create(&pipeline, cache,
|
result = ocf_pipeline_create(&pipeline, cache,
|
||||||
&_ocf_mngt_cache_bind_pipeline_properties);
|
&_ocf_mngt_cache_standby_pipeline_properties);
|
||||||
if (result)
|
if (result)
|
||||||
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_NO_MEM);
|
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_NO_MEM);
|
||||||
|
|
||||||
@ -2385,15 +2430,74 @@ static void _ocf_mngt_cache_bind(ocf_cache_t cache,
|
|||||||
OCF_PL_NEXT_RET(pipeline);
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _ocf_mngt_failover_detach_close_volume(ocf_pipeline_t pipeline,
|
||||||
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
|
{
|
||||||
|
struct ocf_cache_failover_detach_context *context = priv;
|
||||||
|
ocf_cache_t cache = context->cache;
|
||||||
|
|
||||||
|
if (cache->device->volume.opened) {
|
||||||
|
ocf_volume_close(&cache->device->volume);
|
||||||
|
ocf_volume_deinit(&cache->device->volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
ocf_pipeline_next(pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ocf_mngt_cache_failover_detach_finish(ocf_pipeline_t pipeline,
|
||||||
|
void *priv, int error)
|
||||||
|
{
|
||||||
|
struct ocf_cache_failover_detach_context *context = priv;
|
||||||
|
|
||||||
|
context->cmpl(context->priv, error);
|
||||||
|
|
||||||
|
ocf_pipeline_destroy(context->pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ocf_pipeline_properties
|
||||||
|
_ocf_mngt_cache_failover_detach_pipeline_properties = {
|
||||||
|
.priv_size = sizeof(struct ocf_cache_failover_detach_context),
|
||||||
|
.finish = ocf_mngt_cache_failover_detach_finish,
|
||||||
|
.steps = {
|
||||||
|
OCF_PL_STEP(_ocf_mngt_failover_detach_wait_metadata_io),
|
||||||
|
OCF_PL_STEP(_ocf_mngt_failover_detach_close_volume),
|
||||||
|
OCF_PL_STEP_TERMINATOR(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
void _ocf_mngt_cache_failover_detach(ocf_cache_t cache,
|
||||||
|
ocf_mngt_cache_failover_detach_end_t cmpl, void *priv)
|
||||||
|
{
|
||||||
|
struct ocf_cache_failover_detach_context *context;
|
||||||
|
ocf_pipeline_t pipeline;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = ocf_pipeline_create(&pipeline, cache,
|
||||||
|
&_ocf_mngt_cache_failover_detach_pipeline_properties);
|
||||||
|
if (result)
|
||||||
|
OCF_CMPL_RET(priv, -OCF_ERR_NO_MEM);
|
||||||
|
|
||||||
|
context = ocf_pipeline_get_priv(pipeline);
|
||||||
|
|
||||||
|
context->cmpl = cmpl;
|
||||||
|
context->priv = priv;
|
||||||
|
context->pipeline = pipeline;
|
||||||
|
|
||||||
|
context->cache = cache;
|
||||||
|
|
||||||
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _ocf_mngt_cache_activate(ocf_cache_t cache,
|
static void _ocf_mngt_cache_activate(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_device_config *device_cfg,
|
||||||
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
|
||||||
{
|
{
|
||||||
struct ocf_cache_attach_context *context;
|
struct ocf_cache_attach_context *context;
|
||||||
ocf_pipeline_t pipeline;
|
ocf_pipeline_t pipeline;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (!ocf_cache_is_passive(cache))
|
if (!ocf_cache_is_standby(cache))
|
||||||
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_CACHE_EXIST);
|
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_CACHE_EXIST);
|
||||||
|
|
||||||
result = ocf_pipeline_create(&pipeline, cache,
|
result = ocf_pipeline_create(&pipeline, cache,
|
||||||
@ -2401,15 +2505,43 @@ static void _ocf_mngt_cache_activate(ocf_cache_t cache,
|
|||||||
if (result)
|
if (result)
|
||||||
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_NO_MEM);
|
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_NO_MEM);
|
||||||
|
|
||||||
|
if (!ocf_refcnt_frozen(&cache->refcnt.metadata) ||
|
||||||
|
device_cfg->uuid.size == 0) {
|
||||||
|
ocf_cache_log(cache, log_err, "not yet implemented.\n");
|
||||||
|
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_CACHE_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
context = ocf_pipeline_get_priv(pipeline);
|
context = ocf_pipeline_get_priv(pipeline);
|
||||||
|
|
||||||
context->cmpl = cmpl;
|
context->cmpl = cmpl;
|
||||||
context->priv1 = priv1;
|
context->priv1 = priv1;
|
||||||
context->priv2 = priv2;
|
context->priv2 = priv2;
|
||||||
context->pipeline = pipeline;
|
context->pipeline = pipeline;
|
||||||
|
|
||||||
context->cache = cache;
|
context->cache = cache;
|
||||||
context->cfg = *cfg;
|
|
||||||
|
context->cfg.device = *device_cfg;
|
||||||
|
context->cfg.cache_line_size = cache->metadata.line_size;
|
||||||
|
context->cfg.open_cores = true;
|
||||||
|
context->cfg.force = false;
|
||||||
|
context->cfg.discard_on_start = false;
|
||||||
|
|
||||||
|
/* Metadata reference counter not frozen in standby mode
|
||||||
|
* indicates the caching drive is still attached. In
|
||||||
|
* this case it must be frozen now to avoid unwanted
|
||||||
|
* concurrency during management operation.
|
||||||
|
*/
|
||||||
|
if (!ocf_refcnt_frozen(&cache->refcnt.metadata)) {
|
||||||
|
ENV_BUG_ON(!cache->device->volume.opened);
|
||||||
|
context->flags.metadata_frozen = true;
|
||||||
|
ocf_refcnt_freeze(&cache->refcnt.metadata);
|
||||||
|
|
||||||
|
/* Callback set to ocf_pipeline_next directly to
|
||||||
|
* queue pipeline first step upon receiving the
|
||||||
|
* callback. */
|
||||||
|
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
|
||||||
|
(ocf_refcnt_cb_t)ocf_pipeline_next, pipeline);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OCF_PL_NEXT_RET(pipeline);
|
OCF_PL_NEXT_RET(pipeline);
|
||||||
}
|
}
|
||||||
@ -2441,17 +2573,17 @@ static int _ocf_mngt_cache_validate_cfg(struct ocf_mngt_cache_config *cfg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _ocf_mngt_cache_validate_device_cfg(
|
static int _ocf_mngt_cache_validate_attach_cfg(
|
||||||
struct ocf_mngt_cache_device_config *device_cfg)
|
struct ocf_mngt_cache_attach_config *attach_cfg)
|
||||||
{
|
{
|
||||||
if (!device_cfg->uuid.data)
|
if (!attach_cfg->device.uuid.data)
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
if (device_cfg->uuid.size > OCF_VOLUME_UUID_MAX_SIZE)
|
if (attach_cfg->device.uuid.size > OCF_VOLUME_UUID_MAX_SIZE)
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
if (device_cfg->cache_line_size != ocf_cache_line_size_none &&
|
if (attach_cfg->cache_line_size != ocf_cache_line_size_none &&
|
||||||
!ocf_cache_line_size_is_valid(device_cfg->cache_line_size))
|
!ocf_cache_line_size_is_valid(attach_cfg->cache_line_size))
|
||||||
return -OCF_ERR_INVALID_CACHE_LINE_SIZE;
|
return -OCF_ERR_INVALID_CACHE_LINE_SIZE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2528,7 +2660,7 @@ static void _ocf_mngt_cache_attach_complete(ocf_cache_t cache, void *priv1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ocf_mngt_cache_attach(ocf_cache_t cache,
|
void ocf_mngt_cache_attach(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_attach_config *cfg,
|
||||||
ocf_mngt_cache_attach_end_t cmpl, void *priv)
|
ocf_mngt_cache_attach_end_t cmpl, void *priv)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
@ -2539,7 +2671,7 @@ void ocf_mngt_cache_attach(ocf_cache_t cache,
|
|||||||
if (!cache->mngt_queue)
|
if (!cache->mngt_queue)
|
||||||
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
||||||
|
|
||||||
result = _ocf_mngt_cache_validate_device_cfg(cfg);
|
result = _ocf_mngt_cache_validate_attach_cfg(cfg);
|
||||||
if (result)
|
if (result)
|
||||||
OCF_CMPL_RET(cache, priv, result);
|
OCF_CMPL_RET(cache, priv, result);
|
||||||
|
|
||||||
@ -2635,7 +2767,7 @@ static void _ocf_mngt_cache_load_complete(ocf_cache_t cache, void *priv1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ocf_mngt_cache_load(ocf_cache_t cache,
|
void ocf_mngt_cache_load(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_attach_config *cfg,
|
||||||
ocf_mngt_cache_load_end_t cmpl, void *priv)
|
ocf_mngt_cache_load_end_t cmpl, void *priv)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
@ -2657,14 +2789,14 @@ void ocf_mngt_cache_load(ocf_cache_t cache,
|
|||||||
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = _ocf_mngt_cache_validate_device_cfg(cfg);
|
result = _ocf_mngt_cache_validate_attach_cfg(cfg);
|
||||||
if (result)
|
if (result)
|
||||||
OCF_CMPL_RET(cache, priv, result);
|
OCF_CMPL_RET(cache, priv, result);
|
||||||
|
|
||||||
_ocf_mngt_cache_load(cache, cfg, _ocf_mngt_cache_load_complete, cmpl, priv);
|
_ocf_mngt_cache_load(cache, cfg, _ocf_mngt_cache_load_complete, cmpl, priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_cache_bind_complete(ocf_cache_t cache, void *priv1,
|
static void _ocf_mngt_cache_standby_complete(ocf_cache_t cache, void *priv1,
|
||||||
void *priv2, int error)
|
void *priv2, int error)
|
||||||
{
|
{
|
||||||
ocf_mngt_cache_bind_end_t cmpl = priv1;
|
ocf_mngt_cache_bind_end_t cmpl = priv1;
|
||||||
@ -2678,8 +2810,8 @@ static void _ocf_mngt_cache_bind_complete(ocf_cache_t cache, void *priv1,
|
|||||||
OCF_CMPL_RET(cache, priv2, 0);
|
OCF_CMPL_RET(cache, priv2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ocf_mngt_cache_bind(ocf_cache_t cache,
|
void ocf_mngt_cache_standby(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_attach_config *cfg,
|
||||||
ocf_mngt_cache_bind_end_t cmpl, void *priv)
|
ocf_mngt_cache_bind_end_t cmpl, void *priv)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
@ -2701,18 +2833,18 @@ void ocf_mngt_cache_bind(ocf_cache_t cache,
|
|||||||
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = _ocf_mngt_cache_validate_device_cfg(cfg);
|
result = _ocf_mngt_cache_validate_attach_cfg(cfg);
|
||||||
if (result)
|
if (result)
|
||||||
OCF_CMPL_RET(cache, priv, result);
|
OCF_CMPL_RET(cache, priv, result);
|
||||||
|
|
||||||
_ocf_mngt_cache_bind(cache, cfg, _ocf_mngt_cache_bind_complete,
|
_ocf_mngt_cache_standby(cache, cfg, _ocf_mngt_cache_standby_complete,
|
||||||
cmpl, priv);
|
cmpl, priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ocf_mngt_cache_activate_complete(ocf_cache_t cache, void *priv1,
|
static void _ocf_mngt_cache_activate_complete(ocf_cache_t cache, void *priv1,
|
||||||
void *priv2, int error)
|
void *priv2, int error)
|
||||||
{
|
{
|
||||||
ocf_mngt_cache_bind_end_t cmpl = priv1;
|
ocf_mngt_cache_activate_end_t cmpl = priv1;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
OCF_CMPL_RET(cache, priv2, error);
|
OCF_CMPL_RET(cache, priv2, error);
|
||||||
@ -2723,34 +2855,37 @@ static void _ocf_mngt_cache_activate_complete(ocf_cache_t cache, void *priv1,
|
|||||||
OCF_CMPL_RET(cache, priv2, 0);
|
OCF_CMPL_RET(cache, priv2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ocf_mngt_cache_failover_detach(ocf_cache_t cache,
|
||||||
|
ocf_mngt_cache_failover_detach_end_t cmpl, void *priv)
|
||||||
|
{
|
||||||
|
OCF_CHECK_NULL(cache);
|
||||||
|
|
||||||
|
if (!cache->mngt_queue)
|
||||||
|
OCF_CMPL_RET(priv, -OCF_ERR_INVAL);
|
||||||
|
|
||||||
|
if (!ocf_cache_is_standby(cache))
|
||||||
|
OCF_CMPL_RET(priv, -OCF_ERR_CACHE_EXIST);
|
||||||
|
|
||||||
|
if (ocf_refcnt_frozen(&cache->refcnt.metadata))
|
||||||
|
OCF_CMPL_RET(priv, -OCF_ERR_INVAL);
|
||||||
|
|
||||||
|
ENV_BUG_ON(!cache->device->volume.opened);
|
||||||
|
|
||||||
|
_ocf_mngt_cache_failover_detach(cache, cmpl, priv);
|
||||||
|
}
|
||||||
|
|
||||||
void ocf_mngt_cache_activate(ocf_cache_t cache,
|
void ocf_mngt_cache_activate(ocf_cache_t cache,
|
||||||
struct ocf_mngt_cache_device_config *cfg,
|
struct ocf_mngt_cache_device_config *cfg,
|
||||||
ocf_mngt_cache_activate_end_t cmpl, void *priv)
|
ocf_mngt_cache_activate_end_t cmpl, void *priv)
|
||||||
{
|
{
|
||||||
int result;
|
|
||||||
|
|
||||||
OCF_CHECK_NULL(cache);
|
OCF_CHECK_NULL(cache);
|
||||||
OCF_CHECK_NULL(cfg);
|
OCF_CHECK_NULL(cfg);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg->cache_line_size != ocf_cache_line_size_none &&
|
|
||||||
cfg->cache_line_size != cache->metadata.line_size) {
|
|
||||||
ocf_cache_log(cache, log_err, "Specifying cache line size is "
|
|
||||||
"forbidden for activate operation.");
|
|
||||||
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cache->mngt_queue)
|
if (!cache->mngt_queue)
|
||||||
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
||||||
|
|
||||||
result = _ocf_mngt_cache_validate_device_cfg(cfg);
|
if (cfg->uuid.size > OCF_VOLUME_UUID_MAX_SIZE)
|
||||||
if (result)
|
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
||||||
OCF_CMPL_RET(cache, priv, result);
|
|
||||||
|
|
||||||
_ocf_mngt_cache_activate(cache, cfg, _ocf_mngt_cache_activate_complete,
|
_ocf_mngt_cache_activate(cache, cfg, _ocf_mngt_cache_activate_complete,
|
||||||
cmpl, priv);
|
cmpl, priv);
|
||||||
|
@ -56,10 +56,10 @@ bool ocf_cache_is_running(ocf_cache_t cache)
|
|||||||
return env_bit_test(ocf_cache_state_running, &cache->cache_state);
|
return env_bit_test(ocf_cache_state_running, &cache->cache_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ocf_cache_is_passive(ocf_cache_t cache)
|
bool ocf_cache_is_standby(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
OCF_CHECK_NULL(cache);
|
OCF_CHECK_NULL(cache);
|
||||||
return env_bit_test(ocf_cache_state_passive, &cache->cache_state);
|
return env_bit_test(ocf_cache_state_standby, &cache->cache_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ocf_cache_is_device_attached(ocf_cache_t cache)
|
bool ocf_cache_is_device_attached(ocf_cache_t cache)
|
||||||
@ -107,7 +107,9 @@ int ocf_cache_get_info(ocf_cache_t cache, struct ocf_cache_info *info)
|
|||||||
_ocf_stats_zero(&info->inactive);
|
_ocf_stats_zero(&info->inactive);
|
||||||
|
|
||||||
info->attached = ocf_cache_is_device_attached(cache);
|
info->attached = ocf_cache_is_device_attached(cache);
|
||||||
if (info->attached) {
|
info->failover_detached = ocf_cache_is_standby(cache) &&
|
||||||
|
ocf_refcnt_frozen(&cache->refcnt.metadata);
|
||||||
|
if (info->attached && !info->failover_detached) {
|
||||||
info->volume_type = ocf_ctx_get_volume_type_id(cache->owner,
|
info->volume_type = ocf_ctx_get_volume_type_id(cache->owner,
|
||||||
cache->device->volume.type);
|
cache->device->volume.type);
|
||||||
info->size = cache->conf_meta->cachelines;
|
info->size = cache->conf_meta->cachelines;
|
||||||
@ -119,7 +121,7 @@ int ocf_cache_get_info(ocf_cache_t cache, struct ocf_cache_info *info)
|
|||||||
info->metadata_footprint = ocf_cache_is_device_attached(cache) ?
|
info->metadata_footprint = ocf_cache_is_device_attached(cache) ?
|
||||||
ocf_metadata_size_of(cache) : 0;
|
ocf_metadata_size_of(cache) : 0;
|
||||||
|
|
||||||
if (env_bit_test(ocf_cache_state_passive, &cache->cache_state))
|
if (ocf_cache_is_standby(cache))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
info->core_count = cache->conf_meta->core_count;
|
info->core_count = cache->conf_meta->core_count;
|
||||||
|
@ -62,11 +62,18 @@ class CacheConfig(Structure):
|
|||||||
class CacheDeviceConfig(Structure):
|
class CacheDeviceConfig(Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
("_uuid", Uuid),
|
("_uuid", Uuid),
|
||||||
("_cache_line_size", c_uint64),
|
|
||||||
("_volume_type", c_uint8),
|
("_volume_type", c_uint8),
|
||||||
("_force", c_bool),
|
|
||||||
("_min_free_ram", c_uint64),
|
|
||||||
("_perform_test", c_bool),
|
("_perform_test", c_bool),
|
||||||
|
("_volume_params", c_void_p),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class CacheAttachConfig(Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("_device", CacheDeviceConfig),
|
||||||
|
("_cache_line_size", c_uint64),
|
||||||
|
("_open_cores", c_bool),
|
||||||
|
("_force", c_bool),
|
||||||
("_discard_on_start", c_bool),
|
("_discard_on_start", c_bool),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -324,7 +331,9 @@ class Cache:
|
|||||||
self.write_unlock()
|
self.write_unlock()
|
||||||
|
|
||||||
if status:
|
if status:
|
||||||
raise OcfError("Error setting cache seq cut off policy promotion count", status)
|
raise OcfError(
|
||||||
|
"Error setting cache seq cut off policy promotion count", status
|
||||||
|
)
|
||||||
|
|
||||||
def get_partition_info(self, part_id: int):
|
def get_partition_info(self, part_id: int):
|
||||||
ioclass_info = IoClassInfo()
|
ioclass_info = IoClassInfo()
|
||||||
@ -349,7 +358,13 @@ class Cache:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def add_partition(
|
def add_partition(
|
||||||
self, part_id: int, name: str, min_size: int, max_size: int, priority: int, valid: bool
|
self,
|
||||||
|
part_id: int,
|
||||||
|
name: str,
|
||||||
|
min_size: int,
|
||||||
|
max_size: int,
|
||||||
|
priority: int,
|
||||||
|
valid: bool,
|
||||||
):
|
):
|
||||||
self.write_lock()
|
self.write_lock()
|
||||||
|
|
||||||
@ -414,7 +429,8 @@ class Cache:
|
|||||||
):
|
):
|
||||||
self.device = device
|
self.device = device
|
||||||
self.device_name = device.uuid
|
self.device_name = device.uuid
|
||||||
self.dev_cfg = CacheDeviceConfig(
|
|
||||||
|
device_config = CacheDeviceConfig(
|
||||||
_uuid=Uuid(
|
_uuid=Uuid(
|
||||||
_data=cast(
|
_data=cast(
|
||||||
create_string_buffer(self.device_name.encode("ascii")), c_char_p
|
create_string_buffer(self.device_name.encode("ascii")), c_char_p
|
||||||
@ -422,12 +438,17 @@ class Cache:
|
|||||||
_size=len(self.device_name) + 1,
|
_size=len(self.device_name) + 1,
|
||||||
),
|
),
|
||||||
_volume_type=device.type_id,
|
_volume_type=device.type_id,
|
||||||
|
_perform_test=perform_test,
|
||||||
|
_volume_params=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.dev_cfg = CacheAttachConfig(
|
||||||
|
_device=device_config,
|
||||||
_cache_line_size=cache_line_size
|
_cache_line_size=cache_line_size
|
||||||
if cache_line_size
|
if cache_line_size
|
||||||
else self.cache_line_size,
|
else self.cache_line_size,
|
||||||
_force=force,
|
_force=force,
|
||||||
_min_free_ram=0,
|
_open_cores=True,
|
||||||
_perform_test=perform_test,
|
|
||||||
_discard_on_start=False,
|
_discard_on_start=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -454,9 +475,7 @@ class Cache:
|
|||||||
|
|
||||||
c = OcfCompletion([("cache", c_void_p), ("priv", c_void_p), ("error", c_int)])
|
c = OcfCompletion([("cache", c_void_p), ("priv", c_void_p), ("error", c_int)])
|
||||||
|
|
||||||
self.owner.lib.ocf_mngt_cache_detach(
|
self.owner.lib.ocf_mngt_cache_detach(self.cache_handle, c, None)
|
||||||
self.cache_handle, c, None
|
|
||||||
)
|
|
||||||
|
|
||||||
c.wait()
|
c.wait()
|
||||||
self.write_unlock()
|
self.write_unlock()
|
||||||
@ -706,7 +725,12 @@ lib.ocf_mngt_cache_remove_core.argtypes = [c_void_p, c_void_p, c_void_p]
|
|||||||
lib.ocf_mngt_cache_add_core.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p]
|
lib.ocf_mngt_cache_add_core.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p]
|
||||||
lib.ocf_cache_get_name.argtypes = [c_void_p]
|
lib.ocf_cache_get_name.argtypes = [c_void_p]
|
||||||
lib.ocf_cache_get_name.restype = c_char_p
|
lib.ocf_cache_get_name.restype = c_char_p
|
||||||
lib.ocf_mngt_cache_cleaning_set_policy.argtypes = [c_void_p, c_uint32, c_void_p, c_void_p]
|
lib.ocf_mngt_cache_cleaning_set_policy.argtypes = [
|
||||||
|
c_void_p,
|
||||||
|
c_uint32,
|
||||||
|
c_void_p,
|
||||||
|
c_void_p,
|
||||||
|
]
|
||||||
lib.ocf_mngt_core_set_seq_cutoff_policy_all.argtypes = [c_void_p, c_uint32]
|
lib.ocf_mngt_core_set_seq_cutoff_policy_all.argtypes = [c_void_p, c_uint32]
|
||||||
lib.ocf_mngt_core_set_seq_cutoff_policy_all.restype = c_int
|
lib.ocf_mngt_core_set_seq_cutoff_policy_all.restype = c_int
|
||||||
lib.ocf_mngt_core_set_seq_cutoff_threshold_all.argtypes = [c_void_p, c_uint32]
|
lib.ocf_mngt_core_set_seq_cutoff_threshold_all.argtypes = [c_void_p, c_uint32]
|
||||||
|
Loading…
Reference in New Issue
Block a user