Allow waiting for metadata flush to be interrupted.

When context was allocated on the stack and waiting for completion was
interrupted, completion function would attempt to save flush result in
memory which might in use by other process. This would cause a system crash.

To prevent such scenario, context is allocated dynamiclly and extended with
reference counter. In case of interrupt, completion function doesn't have to
save result in context, it can simply free it's memory.

This commit is part of patch that will allow to interrupt waiting for OCF
operations.

Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
Michal Mielewczyk 2019-12-17 02:54:41 -05:00
parent de823b15fc
commit b7f1dd69a9

View File

@ -165,22 +165,33 @@ static int _cache_mngt_read_lock_sync(ocf_cache_t cache)
static void _cache_mngt_save_sync_complete(ocf_cache_t cache, void *priv, static void _cache_mngt_save_sync_complete(ocf_cache_t cache, void *priv,
int error) int error)
{ {
struct _cache_mngt_sync_context *context = priv; struct _cache_mngt_async_context *context = priv;
int result;
*context->result = error; result = _cache_mngt_async_callee_set_result(context, error);
complete(&context->compl);
if (result == -KCAS_ERR_WAITING_INTERRUPTED)
kfree(context);
} }
static int _cache_mngt_save_sync(ocf_cache_t cache) static int _cache_mngt_save_sync(ocf_cache_t cache)
{ {
struct _cache_mngt_sync_context context; struct _cache_mngt_async_context *context;
int result; int result;
init_completion(&context.compl); context = kmalloc(sizeof(*context), GFP_KERNEL);
context.result = &result; if (!context)
return -ENOMEM;
ocf_mngt_cache_save(cache, _cache_mngt_save_sync_complete, &context); _cache_mngt_async_context_init(context);
wait_for_completion_interruptible(&context.compl);
ocf_mngt_cache_save(cache, _cache_mngt_save_sync_complete, context);
result = wait_for_completion_interruptible(&context->cmpl);
result = _cache_mngt_async_caller_set_result(context, result);
if (result != -KCAS_ERR_WAITING_INTERRUPTED)
kfree(context);
return result; return result;
} }