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;
|
struct ocf_io_meta *io_meta;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
data = env_allocator_new(volume->type->allocator);
|
if (!ocf_refcnt_inc(&volume->refcnt))
|
||||||
if (!data)
|
|
||||||
return NULL;
|
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 = data + sizeof(struct ocf_io_meta);
|
||||||
|
|
||||||
io_meta = ocf_io_get_meta(io);
|
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))
|
if (env_atomic_dec_return(&io_meta->ref_count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ocf_refcnt_dec(&io->volume->refcnt);
|
||||||
|
|
||||||
env_allocator_del(io->volume->type->allocator,
|
env_allocator_del(io->volume->type->allocator,
|
||||||
(void *)io - sizeof(struct ocf_io_meta));
|
(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)
|
if (!volume->priv)
|
||||||
return -OCF_ERR_NO_MEM;
|
return -OCF_ERR_NO_MEM;
|
||||||
|
|
||||||
|
ocf_refcnt_init(&volume->refcnt);
|
||||||
|
ocf_refcnt_freeze(&volume->refcnt);
|
||||||
|
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
volume->uuid.size = 0;
|
volume->uuid.size = 0;
|
||||||
volume->uuid.data = NULL;
|
volume->uuid.data = NULL;
|
||||||
@ -109,6 +112,7 @@ int ocf_volume_init(ocf_volume_t volume, ocf_volume_type_t type,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
ocf_refcnt_unfreeze(&volume->refcnt);
|
||||||
env_free(volume->priv);
|
env_free(volume->priv);
|
||||||
return -OCF_ERR_NO_MEM;
|
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->priv = from->priv;
|
||||||
volume->cache = from->cache;
|
volume->cache = from->cache;
|
||||||
volume->features = from->features;
|
volume->features = from->features;
|
||||||
|
volume->refcnt = from->refcnt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deinitialize original volume without freeing resources.
|
* 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)
|
struct ocf_io *ocf_volume_new_io(ocf_volume_t volume)
|
||||||
{
|
{
|
||||||
if (!volume->opened)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return ocf_io_new(volume);
|
return ocf_io_new(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,16 +278,32 @@ int ocf_volume_open(ocf_volume_t volume, void *volume_params)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ocf_refcnt_unfreeze(&volume->refcnt);
|
||||||
volume->opened = true;
|
volume->opened = true;
|
||||||
|
|
||||||
return 0;
|
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)
|
void ocf_volume_close(ocf_volume_t volume)
|
||||||
{
|
{
|
||||||
|
env_completion cmpl;
|
||||||
|
|
||||||
ENV_BUG_ON(!volume->type->properties->ops.close);
|
ENV_BUG_ON(!volume->type->properties->ops.close);
|
||||||
ENV_BUG_ON(!volume->opened);
|
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->type->properties->ops.close(volume);
|
||||||
volume->opened = false;
|
volume->opened = false;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "ocf_env.h"
|
#include "ocf_env.h"
|
||||||
#include "ocf_io_priv.h"
|
#include "ocf_io_priv.h"
|
||||||
|
#include "utils/utils_refcnt.h"
|
||||||
|
|
||||||
struct ocf_volume_type {
|
struct ocf_volume_type {
|
||||||
const struct ocf_volume_properties *properties;
|
const struct ocf_volume_properties *properties;
|
||||||
@ -26,6 +27,7 @@ struct ocf_volume {
|
|||||||
unsigned discard_zeroes:1;
|
unsigned discard_zeroes:1;
|
||||||
/* true if reading discarded pages returns 0 */
|
/* true if reading discarded pages returns 0 */
|
||||||
} features;
|
} features;
|
||||||
|
struct ocf_refcnt refcnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
int ocf_volume_type_init(struct ocf_volume_type **type,
|
int ocf_volume_type_init(struct ocf_volume_type **type,
|
||||||
|
@ -5,6 +5,14 @@
|
|||||||
|
|
||||||
#include "../utils/utils_refcnt.h"
|
#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)
|
void ocf_refcnt_dec(struct ocf_refcnt *rc)
|
||||||
{
|
{
|
||||||
int val = env_atomic_dec_return(&rc->counter);
|
int val = env_atomic_dec_return(&rc->counter);
|
||||||
|
@ -19,6 +19,9 @@ struct ocf_refcnt
|
|||||||
void *priv;
|
void *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Initialize reference counter */
|
||||||
|
void ocf_refcnt_init(struct ocf_refcnt *rc);
|
||||||
|
|
||||||
/* Try to increment counter. Returns true if successfull, false if freezed */
|
/* Try to increment counter. Returns true if successfull, false if freezed */
|
||||||
bool ocf_refcnt_inc(struct ocf_refcnt *rc);
|
bool ocf_refcnt_inc(struct ocf_refcnt *rc);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user