Merge pull request #802 from arutk/stop_error_handling
Properly handle flush error in cache stop
This commit is contained in:
commit
c46c638e2e
@ -466,6 +466,7 @@ static int _cache_mngt_core_flush_uninterruptible(ocf_core_t core)
|
|||||||
struct _cache_mngt_stop_context {
|
struct _cache_mngt_stop_context {
|
||||||
struct _cache_mngt_async_context async;
|
struct _cache_mngt_async_context async;
|
||||||
int error;
|
int error;
|
||||||
|
int flush_status;
|
||||||
ocf_cache_t cache;
|
ocf_cache_t cache;
|
||||||
struct task_struct *finish_thread;
|
struct task_struct *finish_thread;
|
||||||
};
|
};
|
||||||
@ -484,21 +485,21 @@ static int exit_instance_finish(void *data)
|
|||||||
struct cache_priv *cache_priv;
|
struct cache_priv *cache_priv;
|
||||||
struct _cache_mngt_stop_context *ctx = data;
|
struct _cache_mngt_stop_context *ctx = data;
|
||||||
ocf_queue_t mngt_queue;
|
ocf_queue_t mngt_queue;
|
||||||
bool flush_status;
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
if (kthread_should_stop())
|
if (kthread_should_stop())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
flush_status = ocf_mngt_cache_is_dirty(ctx->cache);
|
|
||||||
cache_priv = ocf_cache_get_priv(ctx->cache);
|
cache_priv = ocf_cache_get_priv(ctx->cache);
|
||||||
mngt_queue = cache_priv->mngt_queue;
|
mngt_queue = cache_priv->mngt_queue;
|
||||||
|
|
||||||
if (ctx->error && ctx->error != -OCF_ERR_WRITE_CACHE)
|
if (ctx->error && ctx->error != -OCF_ERR_WRITE_CACHE)
|
||||||
BUG_ON(ctx->error);
|
BUG_ON(ctx->error);
|
||||||
|
|
||||||
if (!ctx->error && flush_status)
|
if (!ctx->error && ctx->flush_status)
|
||||||
result = -KCAS_ERR_STOPPED_DIRTY;
|
result = -KCAS_ERR_STOPPED_DIRTY;
|
||||||
|
else
|
||||||
|
result = ctx->error;
|
||||||
|
|
||||||
cas_cls_deinit(ctx->cache);
|
cas_cls_deinit(ctx->cache);
|
||||||
|
|
||||||
@ -2427,15 +2428,8 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush)
|
|||||||
*/
|
*/
|
||||||
if (flush)
|
if (flush)
|
||||||
status = _cache_flush_with_lock(cache);
|
status = _cache_flush_with_lock(cache);
|
||||||
switch (status) {
|
if (status)
|
||||||
case -OCF_ERR_CACHE_IN_INCOMPLETE_STATE:
|
|
||||||
case -OCF_ERR_FLUSHING_INTERRUPTED:
|
|
||||||
case -KCAS_ERR_WAITING_INTERRUPTED:
|
|
||||||
goto put;
|
goto put;
|
||||||
default:
|
|
||||||
flush_status = status;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = _cache_mngt_lock_sync(cache);
|
status = _cache_mngt_lock_sync(cache);
|
||||||
if (status)
|
if (status)
|
||||||
@ -2457,10 +2451,6 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush)
|
|||||||
goto stop_thread;
|
goto stop_thread;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (flush_status) {
|
|
||||||
status = flush_status;
|
|
||||||
goto stop_thread;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* We are being switched to upgrade in flight mode -
|
* We are being switched to upgrade in flight mode -
|
||||||
* wait for finishing pending core requests
|
* wait for finishing pending core requests
|
||||||
@ -2471,6 +2461,8 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush)
|
|||||||
/* Flush cache again. This time we don't allow interruption. */
|
/* Flush cache again. This time we don't allow interruption. */
|
||||||
if (flush)
|
if (flush)
|
||||||
flush_status = _cache_mngt_cache_flush_uninterruptible(cache);
|
flush_status = _cache_mngt_cache_flush_uninterruptible(cache);
|
||||||
|
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));
|
||||||
@ -2482,6 +2474,12 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush)
|
|||||||
"Waiting for cache stop interrupted. "
|
"Waiting for cache stop interrupted. "
|
||||||
"Stop will finish asynchronously.\n");
|
"Stop will finish asynchronously.\n");
|
||||||
|
|
||||||
|
if ((status == 0 || status == -KCAS_ERR_WAITING_INTERRUPTED) &&
|
||||||
|
flush_status) {
|
||||||
|
/* "removed dirty" error has a precedence over "interrupted" */
|
||||||
|
return KCAS_ERR_STOPPED_DIRTY;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
stop_thread:
|
stop_thread:
|
||||||
|
@ -67,7 +67,7 @@ done
|
|||||||
SHORT_LINK=$(realpath ${CACHE_DEVICE})
|
SHORT_LINK=$(realpath ${CACHE_DEVICE})
|
||||||
CACHE_DEVICE_OPTION="${CACHE_DEVICE}" turn_off_device
|
CACHE_DEVICE_OPTION="${CACHE_DEVICE}" turn_off_device
|
||||||
for ID in 1 2 3 ; do
|
for ID in 1 2 3 ; do
|
||||||
DONT_FAIL_ON_ERROR_OPTION="YES" CACHE_ID_OPTION="$ID" stop_cache
|
DONT_FAIL_ON_ERROR_OPTION="YES" CACHE_DONT_FLUSH_DATA_OPTION="1" CACHE_ID_OPTION="$ID" stop_cache
|
||||||
done
|
done
|
||||||
CACHE_DEVICE_OPTION="${SHORT_LINK}" turn_on_device
|
CACHE_DEVICE_OPTION="${SHORT_LINK}" turn_on_device
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ done
|
|||||||
SHORT_LINK=$(realpath ${CACHE_DEVICE})
|
SHORT_LINK=$(realpath ${CACHE_DEVICE})
|
||||||
CACHE_DEVICE_OPTION="${CACHE_DEVICE}" turn_off_device
|
CACHE_DEVICE_OPTION="${CACHE_DEVICE}" turn_off_device
|
||||||
for ID in 1 2 3 ; do
|
for ID in 1 2 3 ; do
|
||||||
DONT_FAIL_ON_ERROR_OPTION="YES" CACHE_ID_OPTION="$ID" stop_cache
|
DONT_FAIL_ON_ERROR_OPTION="YES" CACHE_DONT_FLUSH_DATA_OPTION="1" CACHE_ID_OPTION="$ID" stop_cache
|
||||||
done
|
done
|
||||||
CACHE_DEVICE_OPTION="${SHORT_LINK}" turn_on_device
|
CACHE_DEVICE_OPTION="${SHORT_LINK}" turn_on_device
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user