From 35602acb8fee1f9ab72750a7b87887fc6eeb6acf Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 5 Mar 2021 11:35:52 +0100 Subject: [PATCH] Prohibit locking cache while its is being stopped Signed-off-by: Michal Mielewczyk --- casadm/extended_err_msg.c | 4 +++ modules/cas_cache/layer_cache_management.c | 41 +++++++++++++++------- modules/include/cas_ioctl_codes.h | 3 ++ 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/casadm/extended_err_msg.c b/casadm/extended_err_msg.c index b2380ee..e70ea2c 100644 --- a/casadm/extended_err_msg.c +++ b/casadm/extended_err_msg.c @@ -252,6 +252,10 @@ struct { KCAS_ERR_WAITING_INTERRUPTED, "Waiting for operation interrupted" }, + { + KCAS_ERR_CACHE_STOPPING, + "Cache being stopped" + }, }; diff --git a/modules/cas_cache/layer_cache_management.c b/modules/cas_cache/layer_cache_management.c index 78f2478..62c70f1 100644 --- a/modules/cas_cache/layer_cache_management.c +++ b/modules/cas_cache/layer_cache_management.c @@ -98,6 +98,13 @@ static int _cache_mngt_lock_sync(ocf_cache_t cache) struct _cache_mngt_async_context *context; int result; + if (!ocf_cache_is_running(cache)) { + printk(KERN_WARNING "%s is being stopped. " + "Can't perform management operations\n", + ocf_cache_get_name(cache)); + return -KCAS_ERR_CACHE_STOPPING; + } + context = kmalloc(sizeof(*context), GFP_KERNEL); if (!context) return -ENOMEM; @@ -135,6 +142,13 @@ static int _cache_mngt_read_lock_sync(ocf_cache_t cache) struct _cache_mngt_async_context *context; int result; + if (!ocf_cache_is_running(cache)) { + printk(KERN_WARNING "%s is being stopped. " + "Can't perform management operations\n", + ocf_cache_get_name(cache)); + return -KCAS_ERR_CACHE_STOPPING; + } + context = kmalloc(sizeof(*context), GFP_KERNEL); if (!context) return -ENOMEM; @@ -2355,13 +2369,6 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush) mngt_queue = cache_priv->mngt_queue; context = cache_priv->stop_context; - context->finish_thread = kthread_create(exit_instance_finish, - context, "cas_%s_stop", cache_name); - if (IS_ERR(context->finish_thread)) { - status = PTR_ERR(context->finish_thread); - goto put; - } - /* * Flush cache. Flushing may take a long time, so we allow user * to interrupt this operation. Hence we do first flush before @@ -2377,7 +2384,8 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush) case -OCF_ERR_CACHE_IN_INCOMPLETE_STATE: case -OCF_ERR_FLUSHING_INTERRUPTED: case -KCAS_ERR_WAITING_INTERRUPTED: - goto stop_thread; + case -KCAS_ERR_CACHE_STOPPING: + goto put; default: flush_status = status; break; @@ -2385,7 +2393,14 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush) status = _cache_mngt_lock_sync(cache); if (status) - goto stop_thread; + goto put; + + context->finish_thread = kthread_create(exit_instance_finish, + context, "cas_%s_stop", cache_name); + if (IS_ERR(context->finish_thread)) { + status = PTR_ERR(context->finish_thread); + goto unlock; + } if (!cas_upgrade_is_in_upgrade()) { /* If we are not in upgrade - destroy cache devices */ @@ -2393,12 +2408,12 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush) if (status != 0) { printk(KERN_WARNING "Failed to remove all cached devices\n"); - goto unlock; + goto stop_thread; } } else { if (flush_status) { status = flush_status; - goto unlock; + goto stop_thread; } /* * We are being switched to upgrade in flight mode - @@ -2423,10 +2438,10 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush) return status; -unlock: - ocf_mngt_cache_unlock(cache); stop_thread: kthread_stop(context->finish_thread); +unlock: + ocf_mngt_cache_unlock(cache); put: ocf_mngt_cache_put(cache); return status; diff --git a/modules/include/cas_ioctl_codes.h b/modules/include/cas_ioctl_codes.h index 44c25b2..32520fe 100644 --- a/modules/include/cas_ioctl_codes.h +++ b/modules/include/cas_ioctl_codes.h @@ -586,6 +586,9 @@ enum kcas_error { /** Waiting for async operation was interrupted*/ KCAS_ERR_WAITING_INTERRUPTED, + + /** Cache already being stopped*/ + KCAS_ERR_CACHE_STOPPING, }; #endif