Merge pull request #125 from arutk/vol_ref_cnt
Wait for IO put in volume close
This commit is contained in:
commit
2af7e7b4de
11
src/ocf_io.c
11
src/ocf_io.c
@ -54,10 +54,15 @@ struct ocf_io *ocf_io_new(ocf_volume_t volume)
|
||||
struct ocf_io_meta *io_meta;
|
||||
void *data;
|
||||
|
||||
data = env_allocator_new(volume->type->allocator);
|
||||
if (!data)
|
||||
if (!ocf_refcnt_inc(&volume->refcnt))
|
||||
return NULL;
|
||||
|
||||
data = env_allocator_new(volume->type->allocator);
|
||||
if (!data) {
|
||||
ocf_refcnt_dec(&volume->refcnt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
io = data + sizeof(struct ocf_io_meta);
|
||||
|
||||
io_meta = ocf_io_get_meta(io);
|
||||
@ -92,6 +97,8 @@ void ocf_io_put(struct ocf_io *io)
|
||||
if (env_atomic_dec_return(&io_meta->ref_count))
|
||||
return;
|
||||
|
||||
ocf_refcnt_dec(&io->volume->refcnt);
|
||||
|
||||
env_allocator_del(io->volume->type->allocator,
|
||||
(void *)io - sizeof(struct ocf_io_meta));
|
||||
}
|
||||
|
@ -79,6 +79,9 @@ int ocf_volume_init(ocf_volume_t volume, ocf_volume_type_t type,
|
||||
if (!volume->priv)
|
||||
return -OCF_ERR_NO_MEM;
|
||||
|
||||
ocf_refcnt_init(&volume->refcnt);
|
||||
ocf_refcnt_freeze(&volume->refcnt);
|
||||
|
||||
if (!uuid) {
|
||||
volume->uuid.size = 0;
|
||||
volume->uuid.data = NULL;
|
||||
@ -109,6 +112,7 @@ int ocf_volume_init(ocf_volume_t volume, ocf_volume_type_t type,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
ocf_refcnt_unfreeze(&volume->refcnt);
|
||||
env_free(volume->priv);
|
||||
return -OCF_ERR_NO_MEM;
|
||||
}
|
||||
@ -137,6 +141,7 @@ void ocf_volume_move(ocf_volume_t volume, ocf_volume_t from)
|
||||
volume->priv = from->priv;
|
||||
volume->cache = from->cache;
|
||||
volume->features = from->features;
|
||||
volume->refcnt = from->refcnt;
|
||||
|
||||
/*
|
||||
* Deinitialize original volume without freeing resources.
|
||||
@ -221,9 +226,6 @@ int ocf_volume_is_atomic(ocf_volume_t volume)
|
||||
|
||||
struct ocf_io *ocf_volume_new_io(ocf_volume_t volume)
|
||||
{
|
||||
if (!volume->opened)
|
||||
return NULL;
|
||||
|
||||
return ocf_io_new(volume);
|
||||
}
|
||||
|
||||
@ -276,16 +278,32 @@ int ocf_volume_open(ocf_volume_t volume, void *volume_params)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ocf_refcnt_unfreeze(&volume->refcnt);
|
||||
volume->opened = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ocf_volume_close_end(void *ctx)
|
||||
{
|
||||
env_completion *cmpl = ctx;
|
||||
|
||||
env_completion_complete(cmpl);
|
||||
}
|
||||
|
||||
void ocf_volume_close(ocf_volume_t volume)
|
||||
{
|
||||
env_completion cmpl;
|
||||
|
||||
ENV_BUG_ON(!volume->type->properties->ops.close);
|
||||
ENV_BUG_ON(!volume->opened);
|
||||
|
||||
env_completion_init(&cmpl);
|
||||
ocf_refcnt_freeze(&volume->refcnt);
|
||||
ocf_refcnt_register_zero_cb(&volume->refcnt, ocf_volume_close_end,
|
||||
&cmpl);
|
||||
env_completion_wait(&cmpl);
|
||||
|
||||
volume->type->properties->ops.close(volume);
|
||||
volume->opened = false;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "ocf_env.h"
|
||||
#include "ocf_io_priv.h"
|
||||
#include "utils/utils_refcnt.h"
|
||||
|
||||
struct ocf_volume_type {
|
||||
const struct ocf_volume_properties *properties;
|
||||
@ -26,6 +27,7 @@ struct ocf_volume {
|
||||
unsigned discard_zeroes:1;
|
||||
/* true if reading discarded pages returns 0 */
|
||||
} features;
|
||||
struct ocf_refcnt refcnt;
|
||||
};
|
||||
|
||||
int ocf_volume_type_init(struct ocf_volume_type **type,
|
||||
|
@ -5,6 +5,14 @@
|
||||
|
||||
#include "../utils/utils_refcnt.h"
|
||||
|
||||
void ocf_refcnt_init(struct ocf_refcnt *rc)
|
||||
{
|
||||
env_atomic_set(&rc->counter, 0);
|
||||
env_atomic_set(&rc->freeze, 0);
|
||||
env_atomic_set(&rc->callback, 0);
|
||||
rc->cb = NULL;
|
||||
}
|
||||
|
||||
void ocf_refcnt_dec(struct ocf_refcnt *rc)
|
||||
{
|
||||
int val = env_atomic_dec_return(&rc->counter);
|
||||
|
@ -19,6 +19,9 @@ struct ocf_refcnt
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/* Initialize reference counter */
|
||||
void ocf_refcnt_init(struct ocf_refcnt *rc);
|
||||
|
||||
/* Try to increment counter. Returns true if successfull, false if freezed */
|
||||
bool ocf_refcnt_inc(struct ocf_refcnt *rc);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user