Merge pull request #791 from mmichal10/remove-core-cleanup
Clean-up 'remove-core' command
This commit is contained in:
commit
8a8572d8bb
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
@ -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)) {
|
||||
|
@ -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 },
|
||||
};
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user