Clean-up 'remove-core' command

Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
Michal Mielewczyk 2021-04-09 10:51:33 +02:00
parent 1cec062f67
commit 083d6fe93e
5 changed files with 79 additions and 70 deletions

View File

@ -1908,7 +1908,7 @@ int remove_core(unsigned int cache_id, unsigned int core_id,
cmd.detach = detach;
if (run_ioctl_interruptible(fd, KCAS_IOCTL_REMOVE_CORE, &cmd,
"Removing core", cache_id, core_id) < 0) {
cmd.detach?"Detaching core":"Removing core", cache_id, core_id) < 0) {
close(fd);
if (cmd.ext_err_code == OCF_ERR_FLUSHING_INTERRUPTED) {
cas_printf(LOG_ERR, "You have interrupted %s of core. "
@ -1920,9 +1920,9 @@ int remove_core(unsigned int cache_id, unsigned int core_id,
"inactive core use '--remove-inactive' "
"command.\n");
return FAILURE;
} else if (cmd.ext_err_code == KCAS_ERR_REMOVED_DIRTY) {
} else if (cmd.ext_err_code == KCAS_ERR_DETACHED) {
print_err(cmd.ext_err_code);
return SUCCESS;
return FAILURE;
} else {
cas_printf(LOG_ERR, "Error while %s core device %d "
"from cache instance %d\n",

View File

@ -225,10 +225,8 @@ struct {
"Formatting of partition is unsupported."
},
{
KCAS_ERR_REMOVED_DIRTY,
"Warning: Core has been removed or detached without flush.\n"
"Core device may contain inconsistent data.\n"
"To access your data please add core back to the cache."
KCAS_ERR_DETACHED,
"Failed to remove core. See dmesg for more information"
},
{
KCAS_ERR_STOPPED_DIRTY,

View File

@ -1320,6 +1320,19 @@ error_affter_lock:
return result;
}
static int _cache_mngt_create_exported_object(ocf_core_t core, void *cntx)
{
int result;
result = block_dev_create_exported_object(core);
if (result)
return result;
result = block_dev_activate_exported_object(core);
return result;
}
static int _cache_mngt_remove_core_flush(ocf_cache_t cache,
struct kcas_remove_core *cmd)
{
@ -1366,35 +1379,6 @@ put:
return result;
}
static int _cache_mngt_remove_core_prepare(ocf_cache_t cache, ocf_core_t core,
struct kcas_remove_core *cmd)
{
int result = 0;
bool core_active;
core_active = ocf_core_get_state(core) == ocf_core_state_active;
if (!core_active) {
if (cmd->detach) {
printk(KERN_WARNING OCF_PREFIX_SHORT
"Cannot detach core which "
"is already inactive!\n");
}
return -OCF_ERR_CORE_IN_INACTIVE_STATE;
} else {
result = block_dev_destroy_exported_object(core);
if (result)
return result;
}
if (cmd->force_no_flush)
return -KCAS_ERR_REMOVED_DIRTY;
result = _cache_mngt_core_flush_uninterruptible(core);
return result ? -KCAS_ERR_REMOVED_DIRTY : 0;
}
static void _cache_mngt_remove_core_complete(void *priv, int error)
{
struct _cache_mngt_sync_context *context = priv;
@ -1403,10 +1387,63 @@ static void _cache_mngt_remove_core_complete(void *priv, int error)
complete(&context->cmpl);
}
static void _cache_mngt_remove_core_fallback(ocf_cache_t cache, ocf_core_t core)
{
struct _cache_mngt_sync_context context;
int result;
printk(KERN_ERR "Removing core failed. Detaching %s.%s\n",
ocf_cache_get_name(cache),
ocf_core_get_name(core));
init_completion(&context.cmpl);
context.result = &result;
ocf_mngt_cache_detach_core(core,
_cache_mngt_remove_core_complete, &context);
wait_for_completion(&context.cmpl);
if (!result)
return;
printk(KERN_ERR "Detaching %s.%s\n failed. Please retry the remove operation",
ocf_cache_get_name(cache),
ocf_core_get_name(core));
}
static int _cache_mngt_remove_core_prepare(ocf_cache_t cache, ocf_core_t core,
struct kcas_remove_core *cmd)
{
int result = 0;
bool core_active;
core_active = ocf_core_get_state(core) == ocf_core_state_active;
if (!core_active)
return -OCF_ERR_CORE_IN_INACTIVE_STATE;
result = block_dev_destroy_exported_object(core);
if (result)
return result;
if (cmd->force_no_flush)
return 0;
result = _cache_mngt_core_flush_uninterruptible(core);
if (!result)
return 0;
_cache_mngt_remove_core_fallback(cache, core);
return -KCAS_ERR_DETACHED;
}
int cache_mngt_remove_core_from_cache(struct kcas_remove_core *cmd)
{
struct _cache_mngt_sync_context context;
int result, prepare_result = 0;
int result;
ocf_cache_t cache;
ocf_core_t core;
@ -1427,14 +1464,8 @@ int cache_mngt_remove_core_from_cache(struct kcas_remove_core *cmd)
goto unlock;
}
/*
* Destroy exported object and flush core again but don't allow for
* interruption - in case of flush error after exported object had been
* destroyed, instead of trying rolling this back we rather detach core
* and then inform user about error.
*/
prepare_result = _cache_mngt_remove_core_prepare(cache, core, cmd);
if (prepare_result && prepare_result != -KCAS_ERR_REMOVED_DIRTY)
result = _cache_mngt_remove_core_prepare(cache, core, cmd);
if (result)
goto unlock;
init_completion(&context.cmpl);
@ -1448,19 +1479,12 @@ int cache_mngt_remove_core_from_cache(struct kcas_remove_core *cmd)
_cache_mngt_remove_core_complete, &context);
}
if (!cmd->force_no_flush && !prepare_result)
BUG_ON(ocf_mngt_core_is_dirty(core));
wait_for_completion(&context.cmpl);
if (!result && !cmd->detach) {
if (!result && !cmd->detach)
mark_core_id_free(cache, cmd->core_id);
}
unlock:
if (!result && prepare_result)
result = prepare_result;
ocf_mngt_cache_unlock(cache);
put:
ocf_mngt_cache_put(cache);
@ -1495,7 +1519,7 @@ int cache_mngt_remove_inactive_core(struct kcas_remove_inactive *cmd)
/*
* Destroy exported object - in case of error during destruction of
* exported object, instead of trying rolling this back we rather
* exported object, instead of trying rolling this back we rather
* inform user about error.
*/
result = block_dev_destroy_exported_object(core);
@ -1635,19 +1659,6 @@ out_get:
return result;
}
static int _cache_mngt_create_exported_object(ocf_core_t core, void *cntx)
{
int result;
result = block_dev_create_exported_object(core);
if (result)
return result;
result = block_dev_activate_exported_object(core);
return result;
}
static int _cache_mngt_destroy_exported_object(ocf_core_t core, void *cntx)
{
if (block_dev_destroy_exported_object(core)) {

View File

@ -63,7 +63,7 @@ struct {
{ KCAS_ERR_NVME_BAD_FORMAT, EINVAL },
{ KCAS_ERR_CONTAINS_PART, EINVAL },
{ KCAS_ERR_A_PART, EINVAL },
{ KCAS_ERR_REMOVED_DIRTY, EIO },
{ KCAS_ERR_DETACHED, EIO },
{ KCAS_ERR_STOPPED_DIRTY, EIO },
{ KCAS_ERR_CORE_IN_ACTIVE_STATE, ENODEV },
};

View File

@ -577,8 +577,8 @@ enum kcas_error {
/** Given device is a partition */
KCAS_ERR_A_PART,
/** Core has been removed, but it may contain dirty data */
KCAS_ERR_REMOVED_DIRTY,
/** Removing core failed and rollback failed too */
KCAS_ERR_DETACHED,
/** Cache has been stopped, but it may contain dirty data */
KCAS_ERR_STOPPED_DIRTY,