Introduce cache bind operation
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
parent
c0110a4d01
commit
17aa424319
@ -68,6 +68,7 @@ static const char *cache_states_name[ocf_cache_state_max + 1] = {
|
|||||||
[ocf_cache_state_stopping] = "Stopping",
|
[ocf_cache_state_stopping] = "Stopping",
|
||||||
[ocf_cache_state_initializing] = "Initializing",
|
[ocf_cache_state_initializing] = "Initializing",
|
||||||
[ocf_cache_state_incomplete] = "Incomplete",
|
[ocf_cache_state_incomplete] = "Incomplete",
|
||||||
|
[ocf_cache_state_passive] = "Passive",
|
||||||
[ocf_cache_state_max] = "Unknown",
|
[ocf_cache_state_max] = "Unknown",
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2775,8 +2776,12 @@ int list_caches(unsigned int list_format, bool by_id_path)
|
|||||||
cache_mode_to_name(curr_cache->mode));
|
cache_mode_to_name(curr_cache->mode));
|
||||||
} else {
|
} else {
|
||||||
tmp_status = get_cache_state_name(curr_cache->state);
|
tmp_status = get_cache_state_name(curr_cache->state);
|
||||||
snprintf(mode_string, sizeof(mode_string), "%s",
|
if (curr_cache->state & (1 << ocf_cache_state_passive)) {
|
||||||
cache_mode_to_name(curr_cache->mode));
|
strncpy(mode_string, "-", sizeof(mode_string));
|
||||||
|
} else {
|
||||||
|
snprintf(mode_string, sizeof(mode_string), "%s",
|
||||||
|
cache_mode_to_name(curr_cache->mode));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(intermediate_file[1], TAG(TREE_BRANCH)
|
fprintf(intermediate_file[1], TAG(TREE_BRANCH)
|
||||||
|
@ -198,6 +198,8 @@ int start_cache_command_handle_option(char *opt, const char **arg)
|
|||||||
command_args_values.cache_id = atoi(arg[0]);
|
command_args_values.cache_id = atoi(arg[0]);
|
||||||
} else if (!strcmp(opt, "load")) {
|
} else if (!strcmp(opt, "load")) {
|
||||||
command_args_values.state = CACHE_INIT_LOAD;
|
command_args_values.state = CACHE_INIT_LOAD;
|
||||||
|
} else if (!strcmp(opt, "bind")) {
|
||||||
|
command_args_values.state = CACHE_INIT_BIND;
|
||||||
} else if (!strcmp(opt, "cache-device")) {
|
} else if (!strcmp(opt, "cache-device")) {
|
||||||
if(validate_device_name(arg[0]) == FAILURE)
|
if(validate_device_name(arg[0]) == FAILURE)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
@ -243,6 +245,7 @@ static cli_option start_options[] = {
|
|||||||
{'d', "cache-device", CACHE_DEVICE_DESC, 1, "DEVICE", CLI_OPTION_REQUIRED},
|
{'d', "cache-device", CACHE_DEVICE_DESC, 1, "DEVICE", CLI_OPTION_REQUIRED},
|
||||||
{'i', "cache-id", CACHE_ID_DESC_LONG, 1, "ID", 0},
|
{'i', "cache-id", CACHE_ID_DESC_LONG, 1, "ID", 0},
|
||||||
{'l', "load", "Load cache metadata from caching device (DANGEROUS - see manual or Admin Guide for details)"},
|
{'l', "load", "Load cache metadata from caching device (DANGEROUS - see manual or Admin Guide for details)"},
|
||||||
|
{'b', "bind", "Bind caching device (DANGEROUS - see manual or Admin Guide for details)"},
|
||||||
{'f', "force", "Force the creation of cache instance"},
|
{'f', "force", "Force the creation of cache instance"},
|
||||||
{'c', "cache-mode", "Set cache mode from available: {"CAS_CLI_HELP_START_CACHE_MODES"} "CAS_CLI_HELP_START_CACHE_MODES_FULL"; without this parameter Write-Through will be set by default", 1, "NAME"},
|
{'c', "cache-mode", "Set cache mode from available: {"CAS_CLI_HELP_START_CACHE_MODES"} "CAS_CLI_HELP_START_CACHE_MODES_FULL"; without this parameter Write-Through will be set by default", 1, "NAME"},
|
||||||
{'x', "cache-line-size", "Set cache line size in kibibytes: {4,8,16,32,64}[KiB] (default: %d)", 1, "NUMBER", CLI_OPTION_DEFAULT_INT, 0, 0, ocf_cache_line_size_default / KiB},
|
{'x', "cache-line-size", "Set cache line size in kibibytes: {4,8,16,32,64}[KiB] (default: %d)", 1, "NUMBER", CLI_OPTION_DEFAULT_INT, 0, 0, ocf_cache_line_size_default / KiB},
|
||||||
@ -293,6 +296,11 @@ int handle_start()
|
|||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command_args_values.state == CACHE_INIT_BIND && command_args_values.force) {
|
||||||
|
cas_printf(LOG_ERR, "Use of 'bind' and 'force' simultaneously is forbidden.\n");
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
cache_device = open(command_args_values.cache_device, O_RDONLY);
|
cache_device = open(command_args_values.cache_device, O_RDONLY);
|
||||||
|
|
||||||
if (cache_device < 0) {
|
if (cache_device < 0) {
|
||||||
|
@ -1215,7 +1215,8 @@ ocf_part_id_t cas_cls_classify(ocf_cache_t cache, struct bio *bio)
|
|||||||
cas_cls_eval_t ret;
|
cas_cls_eval_t ret;
|
||||||
|
|
||||||
cls = cas_get_classifier(cache);
|
cls = cas_get_classifier(cache);
|
||||||
ENV_BUG_ON(!cls);
|
if (!cls)
|
||||||
|
return 0;
|
||||||
|
|
||||||
_cas_cls_get_bio_context(bio, &io);
|
_cas_cls_get_bio_context(bio, &io);
|
||||||
|
|
||||||
|
@ -576,7 +576,8 @@ static int exit_instance_finish(void *data)
|
|||||||
else
|
else
|
||||||
result = ctx->error;
|
result = ctx->error;
|
||||||
|
|
||||||
cas_cls_deinit(ctx->cache);
|
if (!ocf_cache_is_passive(ctx->cache))
|
||||||
|
cas_cls_deinit(ctx->cache);
|
||||||
|
|
||||||
vfree(cache_priv);
|
vfree(cache_priv);
|
||||||
|
|
||||||
@ -1382,19 +1383,6 @@ error_affter_lock:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _cache_mngt_create_exported_object(ocf_core_t core, void *cntx)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
result = kcas_core_create_exported_object(core);
|
|
||||||
if (result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
result = kcas_core_activate_exported_object(core);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _cache_mngt_remove_core_flush(ocf_cache_t cache,
|
static int _cache_mngt_remove_core_flush(ocf_cache_t cache,
|
||||||
struct kcas_remove_core *cmd)
|
struct kcas_remove_core *cmd)
|
||||||
{
|
{
|
||||||
@ -1726,7 +1714,20 @@ out_get:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _cache_mngt_destroy_exported_object(ocf_core_t core, void *cntx)
|
static int _cache_mngt_create_core_exp_obj(ocf_core_t core, void *cntx)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = kcas_core_create_exported_object(core);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = kcas_core_activate_exported_object(core);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _cache_mngt_destroy_core_exp_obj(ocf_core_t core, void *cntx)
|
||||||
{
|
{
|
||||||
if (kcas_core_destroy_exported_object(core)) {
|
if (kcas_core_destroy_exported_object(core)) {
|
||||||
ocf_cache_t cache = ocf_core_get_cache(core);
|
ocf_cache_t cache = ocf_core_get_cache(core);
|
||||||
@ -1739,21 +1740,46 @@ static int _cache_mngt_destroy_exported_object(ocf_core_t core, void *cntx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cache_mngt_initialize_core_objects(ocf_cache_t cache)
|
static int cache_mngt_initialize_core_exported_objects(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = ocf_core_visit(cache, _cache_mngt_create_exported_object, NULL,
|
result = ocf_core_visit(cache, _cache_mngt_create_core_exp_obj, NULL,
|
||||||
true);
|
true);
|
||||||
if (result) {
|
if (result) {
|
||||||
/* Need to cleanup */
|
/* Need to cleanup */
|
||||||
ocf_core_visit(cache, _cache_mngt_destroy_exported_object, NULL,
|
ocf_core_visit(cache, _cache_mngt_destroy_core_exp_obj, NULL,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cache_mngt_destroy_cache_exp_obj(ocf_cache_t cache)
|
||||||
|
{
|
||||||
|
if (kcas_cache_destroy_exported_object(cache)) {
|
||||||
|
printk(KERN_ERR "Cannot destroy %s exported object\n",
|
||||||
|
ocf_cache_get_name(cache));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cache_mngt_initialize_cache_exported_object(ocf_cache_t cache)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = kcas_cache_create_exported_object(cache);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = kcas_cache_activate_exported_object(cache);
|
||||||
|
if (result) {
|
||||||
|
cache_mngt_destroy_cache_exp_obj(cache);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cache_mngt_prepare_cache_cfg(struct ocf_mngt_cache_config *cfg,
|
int cache_mngt_prepare_cache_cfg(struct ocf_mngt_cache_config *cfg,
|
||||||
struct ocf_mngt_cache_device_config *device_cfg,
|
struct ocf_mngt_cache_device_config *device_cfg,
|
||||||
struct kcas_start_cache *cmd)
|
struct kcas_start_cache *cmd)
|
||||||
@ -1812,6 +1838,7 @@ int cache_mngt_prepare_cache_cfg(struct ocf_mngt_cache_config *cfg,
|
|||||||
case CACHE_INIT_LOAD:
|
case CACHE_INIT_LOAD:
|
||||||
device_cfg->open_cores = true;
|
device_cfg->open_cores = true;
|
||||||
case CACHE_INIT_NEW:
|
case CACHE_INIT_NEW:
|
||||||
|
case CACHE_INIT_BIND:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
@ -2042,7 +2069,8 @@ out_bdev:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _cache_start_finalize(ocf_cache_t cache)
|
static int _cache_start_finalize(ocf_cache_t cache,
|
||||||
|
struct kcas_start_cache *cmd)
|
||||||
{
|
{
|
||||||
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
|
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
|
||||||
struct _cache_mngt_attach_context *ctx = cache_priv->attach_context;
|
struct _cache_mngt_attach_context *ctx = cache_priv->attach_context;
|
||||||
@ -2050,21 +2078,37 @@ static int _cache_start_finalize(ocf_cache_t cache)
|
|||||||
|
|
||||||
_cache_mngt_log_cache_device_path(cache, ctx->device_cfg);
|
_cache_mngt_log_cache_device_path(cache, ctx->device_cfg);
|
||||||
|
|
||||||
result = cas_cls_init(cache);
|
if (cmd->init_cache != CACHE_INIT_BIND) {
|
||||||
if (result) {
|
result = cas_cls_init(cache);
|
||||||
ctx->ocf_start_error = result;
|
if (result) {
|
||||||
return result;
|
ctx->ocf_start_error = result;
|
||||||
}
|
return result;
|
||||||
ctx->cls_inited = true;
|
}
|
||||||
|
ctx->cls_inited = true;
|
||||||
result = cache_mngt_initialize_core_objects(cache);
|
|
||||||
if (result) {
|
|
||||||
ctx->ocf_start_error = result;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ocf_core_visit(cache, _cache_mngt_core_device_loaded_visitor,
|
switch(cmd->init_cache) {
|
||||||
NULL, false);
|
case CACHE_INIT_LOAD:
|
||||||
|
result = cache_mngt_initialize_core_exported_objects(cache);
|
||||||
|
if (result) {
|
||||||
|
ctx->ocf_start_error = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
ocf_core_visit(cache, _cache_mngt_core_device_loaded_visitor,
|
||||||
|
NULL, false);
|
||||||
|
break;
|
||||||
|
case CACHE_INIT_BIND:
|
||||||
|
result = cache_mngt_initialize_cache_exported_object(cache);
|
||||||
|
if (result) {
|
||||||
|
ctx->ocf_start_error = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CACHE_INIT_NEW:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
init_instance_complete(ctx, cache);
|
init_instance_complete(ctx, cache);
|
||||||
|
|
||||||
@ -2079,12 +2123,11 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
|||||||
ocf_cache_t cache;
|
ocf_cache_t cache;
|
||||||
struct cache_priv *cache_priv;
|
struct cache_priv *cache_priv;
|
||||||
int result = 0, rollback_result = 0;
|
int result = 0, rollback_result = 0;
|
||||||
bool load = (cmd && cmd->init_cache == CACHE_INIT_LOAD);
|
|
||||||
|
|
||||||
if (!try_module_get(THIS_MODULE))
|
if (!try_module_get(THIS_MODULE))
|
||||||
return -KCAS_ERR_SYSTEM;
|
return -KCAS_ERR_SYSTEM;
|
||||||
|
|
||||||
if (load)
|
if (cmd->init_cache == CACHE_INIT_LOAD)
|
||||||
result = _cache_mngt_check_metadata(cfg, cmd->cache_path_name);
|
result = _cache_mngt_check_metadata(cfg, cmd->cache_path_name);
|
||||||
if (result) {
|
if (result) {
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
@ -2134,12 +2177,22 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
|||||||
cache_priv = ocf_cache_get_priv(cache);
|
cache_priv = ocf_cache_get_priv(cache);
|
||||||
cache_priv->attach_context = context;
|
cache_priv->attach_context = context;
|
||||||
|
|
||||||
if (load) {
|
switch (cmd->init_cache) {
|
||||||
ocf_mngt_cache_load(cache, device_cfg,
|
case CACHE_INIT_NEW:
|
||||||
_cache_mngt_start_complete, context);
|
|
||||||
} else {
|
|
||||||
ocf_mngt_cache_attach(cache, device_cfg,
|
ocf_mngt_cache_attach(cache, device_cfg,
|
||||||
_cache_mngt_start_complete, context);
|
_cache_mngt_start_complete, context);
|
||||||
|
break;
|
||||||
|
case CACHE_INIT_LOAD:
|
||||||
|
ocf_mngt_cache_load(cache, device_cfg,
|
||||||
|
_cache_mngt_start_complete, context);
|
||||||
|
break;
|
||||||
|
case CACHE_INIT_BIND:
|
||||||
|
ocf_mngt_cache_bind(cache, device_cfg,
|
||||||
|
_cache_mngt_start_complete, context);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = -OCF_ERR_INVAL;
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
result = wait_for_completion_interruptible(&context->async.cmpl);
|
result = wait_for_completion_interruptible(&context->async.cmpl);
|
||||||
|
|
||||||
@ -2150,7 +2203,7 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
|||||||
if (result)
|
if (result)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
result = _cache_start_finalize(cache);
|
result = _cache_start_finalize(cache, cmd);
|
||||||
if (result)
|
if (result)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -2474,7 +2527,7 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush)
|
|||||||
* this time, so we need to flush cache again after disabling
|
* this time, so we need to flush cache again after disabling
|
||||||
* exported object. The second flush should be much faster.
|
* exported object. The second flush should be much faster.
|
||||||
*/
|
*/
|
||||||
if (flush)
|
if (flush && ocf_cache_is_running(cache))
|
||||||
status = _cache_flush_with_lock(cache);
|
status = _cache_flush_with_lock(cache);
|
||||||
if (status)
|
if (status)
|
||||||
goto put;
|
goto put;
|
||||||
@ -2494,16 +2547,21 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush)
|
|||||||
status = kcas_cache_destroy_all_core_exported_objects(cache);
|
status = kcas_cache_destroy_all_core_exported_objects(cache);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"Failed to remove all cached devices\n");
|
"Failed to remove all cached devices\n");
|
||||||
|
goto stop_thread;
|
||||||
|
}
|
||||||
|
status = kcas_cache_destroy_exported_object(cache);
|
||||||
|
if (status != 0) {
|
||||||
|
printk(KERN_WARNING
|
||||||
|
"Failed to remove cache exported object\n");
|
||||||
goto stop_thread;
|
goto stop_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush cache again. This time we don't allow interruption. */
|
/* Flush cache again. This time we don't allow interruption. */
|
||||||
if (flush)
|
if (flush && ocf_cache_is_running(cache))
|
||||||
flush_status = _cache_mngt_cache_flush_uninterruptible(cache);
|
flush_status = _cache_mngt_cache_flush_uninterruptible(cache);
|
||||||
context->flush_status = flush_status;
|
context->flush_status = flush_status;
|
||||||
|
|
||||||
|
|
||||||
if (flush && !flush_status)
|
if (flush && !flush_status)
|
||||||
BUG_ON(ocf_mngt_cache_is_dirty(cache));
|
BUG_ON(ocf_mngt_cache_is_dirty(cache));
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#define CACHE_INIT_NEW 0 /**< initialize new metadata from fresh start */
|
#define CACHE_INIT_NEW 0 /**< initialize new metadata from fresh start */
|
||||||
#define CACHE_INIT_LOAD 1 /**< load existing metadata */
|
#define CACHE_INIT_LOAD 1 /**< load existing metadata */
|
||||||
|
#define CACHE_INIT_BIND 2 /**< bind existing metadata */
|
||||||
|
|
||||||
struct kcas_start_cache {
|
struct kcas_start_cache {
|
||||||
/**
|
/**
|
||||||
|
2
ocf
2
ocf
@ -1 +1 @@
|
|||||||
Subproject commit 865d29d0cb93a71ce37a8410914c35005aa6ed54
|
Subproject commit 886c8d4e31e160f36d5ca3d0698a79811c8c0eca
|
Loading…
Reference in New Issue
Block a user