Simplify data object API
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
parent
cbc590e668
commit
4cf4d6d7c7
@ -44,15 +44,6 @@ struct ocf_data_obj_caps {
|
||||
* @brief OCF data object interface declaration
|
||||
*/
|
||||
struct ocf_data_obj_ops {
|
||||
/**
|
||||
* @brief Allocate new IO for this data object
|
||||
*
|
||||
* @param[in] obj Data object for which IO is created
|
||||
* @return IO On success
|
||||
* @return NULL On failure
|
||||
*/
|
||||
struct ocf_io *(*new_io)(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Submit IO on this data object
|
||||
*
|
||||
@ -128,8 +119,11 @@ struct ocf_data_obj_properties {
|
||||
const char *name;
|
||||
/*!< The name of data object operations */
|
||||
|
||||
uint32_t io_context_size;
|
||||
/*!< Size of io context structure */
|
||||
uint32_t io_priv_size;
|
||||
/*!< Size of io private context structure */
|
||||
|
||||
uint32_t dobj_priv_size;
|
||||
/*!< Size of data object private context structure */
|
||||
|
||||
struct ocf_data_obj_caps caps;
|
||||
/*!< Data object capabilities */
|
||||
@ -152,48 +146,10 @@ static inline struct ocf_data_obj_uuid ocf_str_to_uuid(char *str)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get private context of data object
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
*
|
||||
* @return Data object private context
|
||||
*/
|
||||
void *ocf_data_obj_get_priv(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Set private context for data object
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
* @param[in] priv Data object private context to be set
|
||||
*/
|
||||
void ocf_data_obj_set_priv(ocf_data_obj_t obj, void *priv);
|
||||
|
||||
/**
|
||||
* @brief Allocate new io from data object allocator
|
||||
*
|
||||
* @param[in] obj data object handle
|
||||
*
|
||||
* @return ocf_io object on success, otherwise NULL
|
||||
*/
|
||||
struct ocf_io *ocf_data_obj_new_io(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Delete io from data object allocator
|
||||
*
|
||||
* @param[in] io handle to previously allocated io
|
||||
*/
|
||||
void ocf_data_obj_del_io(struct ocf_io* io);
|
||||
|
||||
/**
|
||||
* @brief Return io context data
|
||||
*
|
||||
* @param[in] io ocf io handle
|
||||
*
|
||||
* @return ocf_io private context data
|
||||
*/
|
||||
void *ocf_data_obj_get_data_from_io(struct ocf_io* io);
|
||||
|
||||
/**
|
||||
* @brief Initialize data object
|
||||
*
|
||||
* @param[in] obj data object handle
|
||||
@ -250,6 +206,15 @@ ocf_data_obj_type_t ocf_dobj_get_type(ocf_data_obj_t obj);
|
||||
*/
|
||||
const struct ocf_data_obj_uuid *ocf_dobj_get_uuid(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Get private context of data object
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
*
|
||||
* @return Data object private context
|
||||
*/
|
||||
void *ocf_dobj_get_priv(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Get cache handle for given data object
|
||||
*
|
||||
|
35
inc/ocf_io.h
35
inc/ocf_io.h
@ -139,24 +139,17 @@ struct ocf_io_ops {
|
||||
* @return Data vector from IO
|
||||
*/
|
||||
ctx_data_t *(*get_data)(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Increase reference counter in OCF IO
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
*/
|
||||
void (*get)(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Decrease reference counter in OCF IO
|
||||
*
|
||||
* @note If IO don't have any reference - deallocate it
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
*/
|
||||
void (*put)(struct ocf_io *io);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get IO private context structure
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
*
|
||||
* @return IO private context structure
|
||||
*/
|
||||
void *ocf_io_get_priv(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Configure OCF IO
|
||||
*
|
||||
@ -184,10 +177,7 @@ static inline void ocf_io_configure(struct ocf_io *io, uint64_t addr,
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
*/
|
||||
static inline void ocf_io_get(struct ocf_io *io)
|
||||
{
|
||||
io->ops->get(io);
|
||||
}
|
||||
void ocf_io_get(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Decrease reference counter in OCF IO
|
||||
@ -196,10 +186,7 @@ static inline void ocf_io_get(struct ocf_io *io)
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
*/
|
||||
static inline void ocf_io_put(struct ocf_io *io)
|
||||
{
|
||||
io->ops->put(io);
|
||||
}
|
||||
void ocf_io_put(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Set OCF IO completion function
|
||||
|
@ -131,7 +131,7 @@ struct ocf_cachemng_attach_params {
|
||||
bool device_alloc : 1;
|
||||
/*!< data structure allocated */
|
||||
|
||||
bool uuid_alloc : 1;
|
||||
bool data_obj_inited : 1;
|
||||
/*!< uuid for cache device is allocated */
|
||||
|
||||
bool attached_metadata_inited : 1;
|
||||
@ -436,10 +436,8 @@ static int _ocf_mngt_init_instance_add_cores(
|
||||
* Attach bottom device to core structure
|
||||
* in cache
|
||||
*/
|
||||
core->obj.type = tobj->type;
|
||||
core->obj.priv = tobj->priv;
|
||||
ocf_mngt_core_pool_remove(ocf_cache_get_ctx(cache),
|
||||
tobj);
|
||||
ocf_dobj_move(&core->obj, tobj);
|
||||
ocf_mngt_core_pool_remove(cache->owner, tobj);
|
||||
|
||||
core->opened = true;
|
||||
ocf_cache_log(cache, log_info,
|
||||
@ -623,6 +621,7 @@ static int _ocf_mngt_init_new_cache(struct ocf_cachemng_init_params *params)
|
||||
static int _ocf_mngt_attach_cache_device(struct ocf_cache *cache,
|
||||
struct ocf_cachemng_attach_params *attach_params)
|
||||
{
|
||||
ocf_data_obj_type_t type;
|
||||
int ret;
|
||||
|
||||
cache->device = env_vzalloc(sizeof(*cache->device));
|
||||
@ -633,18 +632,19 @@ static int _ocf_mngt_attach_cache_device(struct ocf_cache *cache,
|
||||
cache->device->obj.cache = cache;
|
||||
|
||||
/* Prepare UUID of cache data object */
|
||||
cache->device->obj.type = ocf_ctx_get_data_obj_type(cache->owner,
|
||||
type = ocf_ctx_get_data_obj_type(cache->owner,
|
||||
attach_params->device_type);
|
||||
if (!cache->device->obj.type) {
|
||||
if (!type) {
|
||||
ret = -OCF_ERR_INVAL_DATA_OBJ_TYPE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ocf_uuid_cache_set(cache, &attach_params->uuid)) {
|
||||
ret = -OCF_ERR_INVAL;
|
||||
ret = ocf_dobj_init(&cache->device->obj, type,
|
||||
&attach_params->uuid, true);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
attach_params->flags.uuid_alloc = true;
|
||||
|
||||
attach_params->flags.data_obj_inited = true;
|
||||
|
||||
/*
|
||||
* Open cache device, It has to be done first because metadata service
|
||||
@ -1098,8 +1098,8 @@ static void _ocf_mngt_attach_handle_error(
|
||||
if (attach_params->flags.concurrency_inited)
|
||||
ocf_concurrency_deinit(cache);
|
||||
|
||||
if (attach_params->flags.uuid_alloc)
|
||||
ocf_uuid_cache_clear(cache);
|
||||
if (attach_params->flags.data_obj_inited)
|
||||
ocf_dobj_deinit(&cache->device->obj);
|
||||
|
||||
if (attach_params->flags.device_alloc)
|
||||
env_vfree(cache->device);
|
||||
@ -1572,7 +1572,7 @@ static int _ocf_mngt_cache_unplug(ocf_cache_t cache, bool stop)
|
||||
ocf_metadata_deinit_variable_size(cache);
|
||||
ocf_concurrency_deinit(cache);
|
||||
|
||||
ocf_uuid_cache_clear(cache);
|
||||
ocf_dobj_deinit(&cache->device->obj);
|
||||
|
||||
env_vfree(cache->device);
|
||||
cache->device = NULL;
|
||||
|
@ -96,7 +96,7 @@ void cache_mng_core_remove_from_meta(struct ocf_cache *cache, int core_id)
|
||||
cache->core_conf_meta[core_id].added = false;
|
||||
|
||||
/* Clear UUID of core */
|
||||
ocf_uuid_core_clear(cache, &cache->core[core_id]);
|
||||
ocf_metadata_clear_core_uuid(&cache->core[core_id]);
|
||||
cache->core_conf_meta[core_id].seq_no = OCF_SEQ_NO_INVALID;
|
||||
|
||||
OCF_METADATA_UNLOCK_WR();
|
||||
|
@ -64,12 +64,14 @@ error_out:
|
||||
static int _ocf_mngt_cache_add_core(ocf_cache_t cache, ocf_core_t *core,
|
||||
struct ocf_mngt_core_config *cfg)
|
||||
{
|
||||
int result = 0;
|
||||
ocf_core_t tmp_core;
|
||||
struct ocf_data_obj_uuid new_uuid;
|
||||
ocf_data_obj_t obj;
|
||||
ocf_data_obj_type_t type;
|
||||
ocf_seq_no_t core_sequence_no;
|
||||
ocf_cleaning_t clean_type;
|
||||
uint64_t length;
|
||||
int result = 0;
|
||||
|
||||
tmp_core = &cache->core[cfg->core_id];
|
||||
obj = &tmp_core->obj;
|
||||
@ -77,14 +79,20 @@ static int _ocf_mngt_cache_add_core(ocf_cache_t cache, ocf_core_t *core,
|
||||
tmp_core->obj.cache = cache;
|
||||
|
||||
/* Set uuid */
|
||||
ocf_uuid_core_set(cache, tmp_core, &cfg->uuid);
|
||||
result = ocf_metadata_set_core_uuid(tmp_core, &cfg->uuid, &new_uuid);
|
||||
if (result)
|
||||
return -OCF_ERR_INVAL;
|
||||
|
||||
obj->type = ocf_ctx_get_data_obj_type(cache->owner, cfg->data_obj_type);
|
||||
if (!obj->type) {
|
||||
type = ocf_ctx_get_data_obj_type(cache->owner, cfg->data_obj_type);
|
||||
if (!type) {
|
||||
result = -OCF_ERR_INVAL_DATA_OBJ_TYPE;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
result = ocf_dobj_init(obj, type, &new_uuid, false);
|
||||
if (result)
|
||||
goto error_out;
|
||||
|
||||
if (cfg->user_metadata.data && cfg->user_metadata.size > 0) {
|
||||
result = ocf_core_set_user_metadata_raw(tmp_core,
|
||||
cfg->user_metadata.data,
|
||||
@ -184,7 +192,7 @@ error_after_clean_pol:
|
||||
error_after_open:
|
||||
ocf_dobj_close(obj);
|
||||
error_out:
|
||||
ocf_uuid_core_clear(cache, tmp_core);
|
||||
ocf_metadata_clear_core_uuid(tmp_core);
|
||||
*core = NULL;
|
||||
return result;
|
||||
}
|
||||
@ -336,17 +344,22 @@ static int _ocf_mngt_find_core_id(ocf_cache_t cache,
|
||||
int ocf_mngt_core_init_front_dobj(ocf_core_t core)
|
||||
{
|
||||
ocf_cache_t cache = ocf_core_get_cache(core);
|
||||
ocf_data_obj_t front_obj;
|
||||
ocf_data_obj_type_t type;
|
||||
struct ocf_data_obj_uuid uuid = {
|
||||
.data = core,
|
||||
.size = sizeof(core),
|
||||
};
|
||||
int ret;
|
||||
|
||||
front_obj = &core->front_obj;
|
||||
front_obj->uuid.data = core;
|
||||
front_obj->uuid.size = sizeof(core);
|
||||
|
||||
front_obj->type = ocf_ctx_get_data_obj_type(cache->owner, 0);
|
||||
if (!front_obj->type)
|
||||
type = ocf_ctx_get_data_obj_type(cache->owner, 0);
|
||||
if (!type)
|
||||
return -OCF_ERR_INVAL;
|
||||
|
||||
return ocf_dobj_open(front_obj);
|
||||
ret = ocf_dobj_init(&core->front_obj, type, &uuid, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ocf_dobj_open(&core->front_obj);
|
||||
}
|
||||
|
||||
int ocf_mngt_cache_add_core_nolock(ocf_cache_t cache, ocf_core_t *core,
|
||||
|
@ -14,6 +14,10 @@
|
||||
#include "utils/utils_device.h"
|
||||
#include "ocf_request.h"
|
||||
|
||||
struct ocf_core_dobj {
|
||||
ocf_core_t core;
|
||||
};
|
||||
|
||||
ocf_cache_t ocf_core_get_cache(ocf_core_t core)
|
||||
{
|
||||
OCF_CHECK_NULL(core);
|
||||
@ -116,10 +120,12 @@ int ocf_core_set_uuid(ocf_core_t core, const struct ocf_data_obj_uuid *uuid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
result = ocf_uuid_core_set(cache, core, uuid);
|
||||
result = ocf_metadata_set_core_uuid(core, uuid, NULL);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
ocf_dobj_set_uuid(&core->obj, uuid);
|
||||
|
||||
result = ocf_metadata_flush_superblock(cache);
|
||||
if (result) {
|
||||
result = -OCF_ERR_WRITE_CACHE;
|
||||
@ -228,12 +234,14 @@ int ocf_core_visit(ocf_cache_t cache, ocf_core_visitor_t visitor, void *cntx,
|
||||
|
||||
static inline struct ocf_core_io *ocf_io_to_core_io(struct ocf_io *io)
|
||||
{
|
||||
return ocf_data_obj_get_data_from_io(io);
|
||||
return ocf_io_get_priv(io);
|
||||
}
|
||||
|
||||
static inline ocf_core_t ocf_data_obj_to_core(ocf_data_obj_t obj)
|
||||
{
|
||||
return ocf_data_obj_get_priv(obj);
|
||||
struct ocf_core_dobj *core_dobj = ocf_dobj_get_priv(obj);
|
||||
|
||||
return core_dobj->core;
|
||||
}
|
||||
|
||||
static inline void inc_dirty_req_counter(struct ocf_core_io *core_io,
|
||||
@ -569,35 +577,19 @@ static void ocf_core_data_obj_submit_discard(struct ocf_io *io)
|
||||
|
||||
/* *** DATA OBJECT OPS *** */
|
||||
|
||||
struct ocf_io *ocf_core_data_obj_new_io(ocf_data_obj_t obj)
|
||||
{
|
||||
struct ocf_core_io *core_io;
|
||||
struct ocf_io *io;
|
||||
|
||||
io = ocf_data_obj_new_io(obj);
|
||||
if (!io)
|
||||
return NULL;
|
||||
|
||||
core_io = ocf_data_obj_get_data_from_io(io);
|
||||
|
||||
env_atomic_set(&core_io->ref_counter, 1);
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
static int ocf_core_data_obj_open(ocf_data_obj_t obj)
|
||||
{
|
||||
struct ocf_core_dobj *core_dobj = ocf_dobj_get_priv(obj);
|
||||
const struct ocf_data_obj_uuid *uuid = ocf_dobj_get_uuid(obj);
|
||||
ocf_core_t core = (ocf_core_t)uuid->data;
|
||||
|
||||
ocf_data_obj_set_priv(obj, core);
|
||||
core_dobj->core = core;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ocf_core_data_obj_close(ocf_data_obj_t obj)
|
||||
{
|
||||
ocf_data_obj_set_priv(obj, NULL);
|
||||
}
|
||||
|
||||
static unsigned int ocf_core_data_obj_get_max_io_size(ocf_data_obj_t obj)
|
||||
@ -643,44 +635,14 @@ static ctx_data_t *ocf_core_io_get_data(struct ocf_io *io)
|
||||
return core_io->data;
|
||||
}
|
||||
|
||||
static void ocf_core_io_get(struct ocf_io *io)
|
||||
{
|
||||
struct ocf_core_io *core_io;
|
||||
|
||||
OCF_CHECK_NULL(io);
|
||||
|
||||
core_io = ocf_io_to_core_io(io);
|
||||
|
||||
ENV_BUG_ON(env_atomic_inc_return(&core_io->ref_counter) < 1);
|
||||
}
|
||||
|
||||
static void ocf_core_io_put(struct ocf_io *io)
|
||||
{
|
||||
struct ocf_core_io *core_io;
|
||||
int value;
|
||||
|
||||
OCF_CHECK_NULL(io);
|
||||
|
||||
core_io = ocf_io_to_core_io(io);
|
||||
value = env_atomic_dec_return(&core_io->ref_counter);
|
||||
|
||||
ENV_BUG_ON(value < 0);
|
||||
|
||||
if (value)
|
||||
return;
|
||||
|
||||
ocf_data_obj_del_io(io);
|
||||
}
|
||||
|
||||
const struct ocf_data_obj_properties ocf_core_data_obj_properties = {
|
||||
.name = "OCF Core",
|
||||
.io_context_size = sizeof(struct ocf_core_io),
|
||||
.io_priv_size = sizeof(struct ocf_core_io),
|
||||
.dobj_priv_size = sizeof(struct ocf_core_dobj),
|
||||
.caps = {
|
||||
.atomic_writes = 0,
|
||||
},
|
||||
.ops = {
|
||||
.new_io = ocf_core_data_obj_new_io,
|
||||
|
||||
.submit_io = ocf_core_data_obj_submit_io,
|
||||
.submit_flush = ocf_core_data_obj_submit_flush,
|
||||
.submit_discard = ocf_core_data_obj_submit_discard,
|
||||
@ -694,8 +656,6 @@ const struct ocf_data_obj_properties ocf_core_data_obj_properties = {
|
||||
.io_ops = {
|
||||
.set_data = ocf_core_io_set_data,
|
||||
.get_data = ocf_core_io_get_data,
|
||||
.get = ocf_core_io_get,
|
||||
.put = ocf_core_io_put,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -19,8 +19,6 @@
|
||||
ocf_core_log_prefix(core, lvl, ": ", fmt, ##__VA_ARGS__)
|
||||
|
||||
struct ocf_core_io {
|
||||
env_atomic ref_counter;
|
||||
|
||||
bool dirty;
|
||||
/*!< Indicates if io leaves dirty data */
|
||||
|
||||
|
@ -11,53 +11,6 @@
|
||||
|
||||
/* *** Bottom interface *** */
|
||||
|
||||
/*
|
||||
* This is io allocator dedicated for bottom devices.
|
||||
* Out IO structure looks like this:
|
||||
* --------------> +-------------------------+
|
||||
* | OCF is aware | |
|
||||
* | of this part. | struct ocf_io_meta |
|
||||
* | | |
|
||||
* | +-------------------------+ <----------------
|
||||
* | | | Bottom adapter |
|
||||
* | | struct ocf_io | is aware of |
|
||||
* | | | this part. |
|
||||
* --------------> +-------------------------+ |
|
||||
* | | |
|
||||
* | Bottom adapter specific | |
|
||||
* | data structure. | |
|
||||
* | | |
|
||||
* +-------------------------+ <----------------
|
||||
*/
|
||||
|
||||
#define OCF_IO_ALLOCATOR_TOTAL_SIZE(size) \
|
||||
(sizeof(struct ocf_io_meta) + sizeof(struct ocf_io) + size)
|
||||
|
||||
static env_allocator *ocf_io_allocator_create(uint32_t size, const char *name)
|
||||
{
|
||||
return env_allocator_create(OCF_IO_ALLOCATOR_TOTAL_SIZE(size), name);
|
||||
}
|
||||
|
||||
static void ocf_io_allocator_destroy(env_allocator *allocator)
|
||||
{
|
||||
env_allocator_destroy(allocator);
|
||||
}
|
||||
|
||||
static struct ocf_io *ocf_io_allocator_new(env_allocator *allocator)
|
||||
{
|
||||
void *data = env_allocator_new(allocator);
|
||||
|
||||
return data ? (data + sizeof(struct ocf_io_meta)) : NULL;
|
||||
}
|
||||
|
||||
static void ocf_io_allocator_del(env_allocator *allocator, struct ocf_io *io)
|
||||
{
|
||||
if (!io)
|
||||
return;
|
||||
|
||||
env_allocator_del(allocator, (void *)io - sizeof(struct ocf_io_meta));
|
||||
}
|
||||
|
||||
/*
|
||||
* Data object type
|
||||
*/
|
||||
@ -69,7 +22,7 @@ int ocf_data_obj_type_init(struct ocf_data_obj_type **type,
|
||||
struct ocf_data_obj_type *new_type;
|
||||
int ret;
|
||||
|
||||
if (!ops->new_io || !ops->submit_io || !ops->open || !ops->close ||
|
||||
if (!ops->submit_io || !ops->open || !ops->close ||
|
||||
!ops->get_max_io_size || !ops->get_length) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -82,7 +35,7 @@ int ocf_data_obj_type_init(struct ocf_data_obj_type **type,
|
||||
return -OCF_ERR_NO_MEM;
|
||||
|
||||
new_type->allocator = ocf_io_allocator_create(
|
||||
properties->io_context_size, properties->name);
|
||||
properties->io_priv_size, properties->name);
|
||||
if (!new_type->allocator) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
@ -105,52 +58,6 @@ void ocf_data_obj_type_deinit(struct ocf_data_obj_type *type)
|
||||
env_free(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Data object backend API
|
||||
*/
|
||||
|
||||
void *ocf_data_obj_get_priv(ocf_data_obj_t obj)
|
||||
{
|
||||
OCF_CHECK_NULL(obj);
|
||||
|
||||
return obj->priv;
|
||||
}
|
||||
|
||||
void ocf_data_obj_set_priv(ocf_data_obj_t obj, void *priv)
|
||||
{
|
||||
OCF_CHECK_NULL(obj);
|
||||
|
||||
obj->priv = priv;
|
||||
}
|
||||
|
||||
struct ocf_io *ocf_data_obj_new_io(ocf_data_obj_t obj)
|
||||
{
|
||||
struct ocf_io *io;
|
||||
|
||||
OCF_CHECK_NULL(obj);
|
||||
|
||||
io = ocf_io_allocator_new(obj->type->allocator);
|
||||
if (!io)
|
||||
return NULL;
|
||||
|
||||
io->obj = obj;
|
||||
io->ops = &obj->type->properties->io_ops;
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
void ocf_data_obj_del_io(struct ocf_io* io)
|
||||
{
|
||||
OCF_CHECK_NULL(io);
|
||||
|
||||
ocf_io_allocator_del(io->obj->type->allocator, io);
|
||||
}
|
||||
|
||||
void *ocf_data_obj_get_data_from_io(struct ocf_io* io)
|
||||
{
|
||||
return (void *)io + sizeof(struct ocf_io);
|
||||
}
|
||||
|
||||
/*
|
||||
* Data object frontend API
|
||||
*/
|
||||
@ -158,12 +65,23 @@ void *ocf_data_obj_get_data_from_io(struct ocf_io* io)
|
||||
int ocf_dobj_init(ocf_data_obj_t obj, ocf_data_obj_type_t type,
|
||||
struct ocf_data_obj_uuid *uuid, bool uuid_copy)
|
||||
{
|
||||
uint32_t priv_size = type->properties->dobj_priv_size;
|
||||
void *data;
|
||||
int ret;
|
||||
|
||||
if (!obj || !type)
|
||||
return -OCF_ERR_INVAL;
|
||||
|
||||
obj->opened = false;
|
||||
obj->type = type;
|
||||
|
||||
obj->priv = env_zalloc(priv_size, ENV_MEM_NORMAL);
|
||||
if (!obj->priv)
|
||||
return -OCF_ERR_NO_MEM;
|
||||
|
||||
if (!uuid) {
|
||||
obj->uuid.size = 0;
|
||||
obj->uuid.data = NULL;
|
||||
obj->uuid_copy = false;
|
||||
return 0;
|
||||
}
|
||||
@ -171,9 +89,17 @@ int ocf_dobj_init(ocf_data_obj_t obj, ocf_data_obj_type_t type,
|
||||
obj->uuid_copy = uuid_copy;
|
||||
|
||||
if (uuid_copy) {
|
||||
obj->uuid.data = env_strdup(uuid->data, ENV_MEM_NORMAL);
|
||||
if (!obj->uuid.data)
|
||||
return -OCF_ERR_NO_MEM;
|
||||
data = env_vmalloc(uuid->size);
|
||||
if (!data)
|
||||
goto err;
|
||||
|
||||
ret = env_memcpy(data, uuid->size, uuid->data, uuid->size);
|
||||
if (ret) {
|
||||
env_vfree(data);
|
||||
goto err;
|
||||
}
|
||||
|
||||
obj->uuid.data = data;
|
||||
} else {
|
||||
obj->uuid.data = uuid->data;
|
||||
}
|
||||
@ -181,14 +107,42 @@ int ocf_dobj_init(ocf_data_obj_t obj, ocf_data_obj_type_t type,
|
||||
obj->uuid.size = uuid->size;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
env_free(obj->priv);
|
||||
return -OCF_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
void ocf_dobj_deinit(ocf_data_obj_t obj)
|
||||
{
|
||||
OCF_CHECK_NULL(obj);
|
||||
|
||||
env_free(obj->priv);
|
||||
|
||||
if (obj->uuid_copy && obj->uuid.data)
|
||||
env_free(obj->uuid.data);
|
||||
env_vfree(obj->uuid.data);
|
||||
}
|
||||
|
||||
void ocf_dobj_move(ocf_data_obj_t obj, ocf_data_obj_t from)
|
||||
{
|
||||
OCF_CHECK_NULL(obj);
|
||||
OCF_CHECK_NULL(from);
|
||||
|
||||
ocf_dobj_deinit(obj);
|
||||
|
||||
obj->opened = from->opened;
|
||||
obj->type = from->type;
|
||||
obj->uuid = from->uuid;
|
||||
obj->uuid_copy = from->uuid_copy;
|
||||
obj->priv = from->priv;
|
||||
obj->cache = from->cache;
|
||||
obj->features = from->features;
|
||||
|
||||
/*
|
||||
* Deinitialize original object without freeing resources.
|
||||
*/
|
||||
from->opened = false;
|
||||
from->priv = NULL;
|
||||
}
|
||||
|
||||
int ocf_dobj_create(ocf_data_obj_t *obj, ocf_data_obj_type_t type,
|
||||
@ -229,14 +183,29 @@ ocf_data_obj_type_t ocf_dobj_get_type(ocf_data_obj_t obj)
|
||||
return obj->type;
|
||||
}
|
||||
|
||||
const struct ocf_data_obj_uuid *ocf_dobj_get_uuid(
|
||||
ocf_data_obj_t obj)
|
||||
const struct ocf_data_obj_uuid *ocf_dobj_get_uuid(ocf_data_obj_t obj)
|
||||
{
|
||||
OCF_CHECK_NULL(obj);
|
||||
|
||||
return &obj->uuid;
|
||||
}
|
||||
|
||||
void ocf_dobj_set_uuid(ocf_data_obj_t obj, const struct ocf_data_obj_uuid *uuid)
|
||||
{
|
||||
OCF_CHECK_NULL(obj);
|
||||
|
||||
if (obj->uuid_copy && obj->uuid.data)
|
||||
env_vfree(obj->uuid.data);
|
||||
|
||||
obj->uuid.data = uuid->data;
|
||||
obj->uuid.size = uuid->size;
|
||||
}
|
||||
|
||||
void *ocf_dobj_get_priv(ocf_data_obj_t obj)
|
||||
{
|
||||
return obj->priv;
|
||||
}
|
||||
|
||||
ocf_cache_t ocf_dobj_get_cache(ocf_data_obj_t obj)
|
||||
{
|
||||
OCF_CHECK_NULL(obj);
|
||||
@ -251,15 +220,19 @@ int ocf_dobj_is_atomic(ocf_data_obj_t obj)
|
||||
|
||||
struct ocf_io *ocf_dobj_new_io(ocf_data_obj_t obj)
|
||||
{
|
||||
ENV_BUG_ON(!obj->type->properties->ops.new_io);
|
||||
if (!obj->opened)
|
||||
return NULL;
|
||||
|
||||
return obj->type->properties->ops.new_io(obj);
|
||||
return ocf_io_new(obj);
|
||||
}
|
||||
|
||||
void ocf_dobj_submit_io(struct ocf_io *io)
|
||||
{
|
||||
ENV_BUG_ON(!io->obj->type->properties->ops.submit_io);
|
||||
|
||||
if (!io->obj->opened)
|
||||
io->end(io, -EIO);
|
||||
|
||||
io->obj->type->properties->ops.submit_io(io);
|
||||
}
|
||||
|
||||
@ -267,6 +240,9 @@ void ocf_dobj_submit_flush(struct ocf_io *io)
|
||||
{
|
||||
ENV_BUG_ON(!io->obj->type->properties->ops.submit_flush);
|
||||
|
||||
if (!io->obj->opened)
|
||||
io->end(io, -EIO);
|
||||
|
||||
if (!io->obj->type->properties->ops.submit_flush) {
|
||||
ocf_io_end(io, 0);
|
||||
return;
|
||||
@ -277,6 +253,9 @@ void ocf_dobj_submit_flush(struct ocf_io *io)
|
||||
|
||||
void ocf_dobj_submit_discard(struct ocf_io *io)
|
||||
{
|
||||
if (!io->obj->opened)
|
||||
io->end(io, -EIO);
|
||||
|
||||
if (!io->obj->type->properties->ops.submit_discard) {
|
||||
ocf_io_end(io, 0);
|
||||
return;
|
||||
@ -287,22 +266,36 @@ void ocf_dobj_submit_discard(struct ocf_io *io)
|
||||
|
||||
int ocf_dobj_open(ocf_data_obj_t obj)
|
||||
{
|
||||
ENV_BUG_ON(!obj->type->properties->ops.open);
|
||||
int ret;
|
||||
|
||||
return obj->type->properties->ops.open(obj);
|
||||
ENV_BUG_ON(!obj->type->properties->ops.open);
|
||||
ENV_BUG_ON(obj->opened);
|
||||
|
||||
ret = obj->type->properties->ops.open(obj);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
obj->opened = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ocf_dobj_close(ocf_data_obj_t obj)
|
||||
{
|
||||
ENV_BUG_ON(!obj->type->properties->ops.close);
|
||||
ENV_BUG_ON(!obj->opened);
|
||||
|
||||
obj->type->properties->ops.close(obj);
|
||||
obj->opened = false;
|
||||
}
|
||||
|
||||
unsigned int ocf_dobj_get_max_io_size(ocf_data_obj_t obj)
|
||||
{
|
||||
ENV_BUG_ON(!obj->type->properties->ops.get_max_io_size);
|
||||
|
||||
if (!obj->opened)
|
||||
return 0;
|
||||
|
||||
return obj->type->properties->ops.get_max_io_size(obj);
|
||||
}
|
||||
|
||||
@ -310,5 +303,8 @@ uint64_t ocf_dobj_get_length(ocf_data_obj_t obj)
|
||||
{
|
||||
ENV_BUG_ON(!obj->type->properties->ops.get_length);
|
||||
|
||||
if (!obj->opened)
|
||||
return 0;
|
||||
|
||||
return obj->type->properties->ops.get_length(obj);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ struct ocf_data_obj_type {
|
||||
struct ocf_data_obj {
|
||||
ocf_data_obj_type_t type;
|
||||
struct ocf_data_obj_uuid uuid;
|
||||
bool opened;
|
||||
bool uuid_copy;
|
||||
void *priv;
|
||||
ocf_cache_t cache;
|
||||
@ -32,6 +33,11 @@ int ocf_data_obj_type_init(struct ocf_data_obj_type **type,
|
||||
|
||||
void ocf_data_obj_type_deinit(struct ocf_data_obj_type *type);
|
||||
|
||||
void ocf_dobj_move(ocf_data_obj_t obj, ocf_data_obj_t from);
|
||||
|
||||
void ocf_dobj_set_uuid(ocf_data_obj_t obj,
|
||||
const struct ocf_data_obj_uuid *uuid);
|
||||
|
||||
static inline void ocf_dobj_submit_metadata(struct ocf_io *io)
|
||||
{
|
||||
ENV_BUG_ON(!io->obj->type->properties->ops.submit_metadata);
|
||||
|
97
src/ocf_io.c
Normal file
97
src/ocf_io.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "ocf/ocf.h"
|
||||
#include "ocf_io_priv.h"
|
||||
#include "ocf_data_obj_priv.h"
|
||||
|
||||
/*
|
||||
* This is io allocator dedicated for bottom devices.
|
||||
* Out IO structure looks like this:
|
||||
* --------------> +-------------------------+
|
||||
* | OCF is aware | |
|
||||
* | of this part. | struct ocf_io_meta |
|
||||
* | | |
|
||||
* | +-------------------------+ <----------------
|
||||
* | | | Bottom adapter |
|
||||
* | | struct ocf_io | is aware of |
|
||||
* | | | this part. |
|
||||
* --------------> +-------------------------+ |
|
||||
* | | |
|
||||
* | Bottom adapter specific | |
|
||||
* | context data structure. | |
|
||||
* | | |
|
||||
* +-------------------------+ <----------------
|
||||
*/
|
||||
|
||||
#define OCF_IO_TOTAL_SIZE(priv_size) (sizeof(struct ocf_io_meta) + \
|
||||
sizeof(struct ocf_io) + priv_size)
|
||||
|
||||
env_allocator *ocf_io_allocator_create(uint32_t size, const char *name)
|
||||
{
|
||||
return env_allocator_create(OCF_IO_TOTAL_SIZE(size), name);
|
||||
}
|
||||
|
||||
void ocf_io_allocator_destroy(env_allocator *allocator)
|
||||
{
|
||||
env_allocator_destroy(allocator);
|
||||
}
|
||||
|
||||
/*
|
||||
* IO internal API
|
||||
*/
|
||||
|
||||
void *ocf_io_get_meta(struct ocf_io* io)
|
||||
{
|
||||
return (void *)io - sizeof(struct ocf_io_meta);
|
||||
}
|
||||
|
||||
struct ocf_io *ocf_io_new(ocf_data_obj_t obj)
|
||||
{
|
||||
struct ocf_io *io;
|
||||
struct ocf_io_meta *io_meta;
|
||||
void *data;
|
||||
|
||||
data = env_allocator_new(obj->type->allocator);
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
io = data + sizeof(struct ocf_io_meta);
|
||||
|
||||
io_meta = ocf_io_get_meta(io);
|
||||
|
||||
io->obj = obj;
|
||||
io->ops = &obj->type->properties->io_ops;
|
||||
env_atomic_set(&io_meta->ref_count, 1);
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
/*
|
||||
* IO external API
|
||||
*/
|
||||
|
||||
void *ocf_io_get_priv(struct ocf_io* io)
|
||||
{
|
||||
return (void *)io + sizeof(struct ocf_io);
|
||||
}
|
||||
|
||||
void ocf_io_get(struct ocf_io *io)
|
||||
{
|
||||
struct ocf_io_meta *io_meta = ocf_io_get_meta(io);
|
||||
|
||||
atomic_inc_return(&io_meta->ref_count);
|
||||
}
|
||||
|
||||
void ocf_io_put(struct ocf_io *io)
|
||||
{
|
||||
struct ocf_io_meta *io_meta = ocf_io_get_meta(io);
|
||||
|
||||
if (atomic_dec_return(&io_meta->ref_count))
|
||||
return;
|
||||
|
||||
env_allocator_del(io->obj->type->allocator,
|
||||
(void *)io - sizeof(struct ocf_io_meta));
|
||||
}
|
@ -6,12 +6,20 @@
|
||||
#ifndef __OCF_IO_PRIV_H__
|
||||
#define __OCF_IO_PRIV_H__
|
||||
|
||||
#include "ocf/ocf.h"
|
||||
#include "ocf_request.h"
|
||||
|
||||
struct ocf_io_meta {
|
||||
env_atomic ref_count;
|
||||
struct ocf_request *req;
|
||||
};
|
||||
|
||||
env_allocator *ocf_io_allocator_create(uint32_t size, const char *name);
|
||||
|
||||
void ocf_io_allocator_destroy(env_allocator *allocator);
|
||||
|
||||
struct ocf_io *ocf_io_new(ocf_data_obj_t obj);
|
||||
|
||||
static inline void ocf_io_start(struct ocf_io *io)
|
||||
{
|
||||
/*
|
||||
|
@ -35,60 +35,30 @@ static inline int _ocf_uuid_set(const struct ocf_data_obj_uuid *uuid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ocf_uuid_cache_set(ocf_cache_t cache,
|
||||
const struct ocf_data_obj_uuid *uuid)
|
||||
static inline int ocf_metadata_set_core_uuid(ocf_core_t core,
|
||||
const struct ocf_data_obj_uuid *uuid,
|
||||
struct ocf_data_obj_uuid *new_uuid)
|
||||
{
|
||||
int result;
|
||||
void *u;
|
||||
|
||||
if (!uuid)
|
||||
return -EINVAL;
|
||||
|
||||
u = env_vmalloc(uuid->size);
|
||||
if (!u)
|
||||
return -ENOMEM;
|
||||
|
||||
cache->device->obj.uuid.size = 0;
|
||||
result = env_memcpy(u, uuid->size,
|
||||
uuid->data, uuid->size);
|
||||
if (result) {
|
||||
env_vfree(u);
|
||||
return result;
|
||||
}
|
||||
|
||||
cache->device->obj.uuid.data = u;
|
||||
cache->device->obj.uuid.size = uuid->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ocf_uuid_cache_clear(ocf_cache_t cache)
|
||||
{
|
||||
env_vfree(cache->device->obj.uuid.data);
|
||||
cache->device->obj.uuid.size = 0;
|
||||
}
|
||||
|
||||
static inline int ocf_uuid_core_set(ocf_cache_t cache, ocf_core_t core,
|
||||
const struct ocf_data_obj_uuid *uuid)
|
||||
{
|
||||
|
||||
struct ocf_data_obj_uuid *cuuid = &ocf_core_get_data_object(core)->uuid;
|
||||
ocf_cache_t cache = ocf_core_get_cache(core);
|
||||
struct ocf_metadata_uuid *muuid = ocf_metadata_get_core_uuid(cache,
|
||||
ocf_core_get_id(core));
|
||||
if (_ocf_uuid_set(uuid, muuid)) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
cuuid->data = muuid->data;
|
||||
cuuid->size = muuid->size;
|
||||
if (_ocf_uuid_set(uuid, muuid))
|
||||
return -ENOBUFS;
|
||||
|
||||
if (new_uuid) {
|
||||
new_uuid->data = muuid->data;
|
||||
new_uuid->size = muuid->size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ocf_uuid_core_clear(ocf_cache_t cache, ocf_core_t core)
|
||||
static inline void ocf_metadata_clear_core_uuid(ocf_core_t core)
|
||||
{
|
||||
struct ocf_data_obj_uuid uuid = { .size = 0, };
|
||||
ocf_uuid_core_set(cache, core, &uuid);
|
||||
|
||||
ocf_metadata_set_core_uuid(core, &uuid, NULL);
|
||||
}
|
||||
|
||||
#endif /* UTILS_MEM_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user