Merge pull request #31 from robertbaldyga/simplify-dobj-api

Simplify data object API
This commit is contained in:
Robert Bałdyga 2019-01-04 17:38:43 +01:00 committed by GitHub
commit 508f172117
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 307 additions and 307 deletions

View File

@ -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
*

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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,

View File

@ -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,
},
};

View File

@ -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 */

View File

@ -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);
}

View File

@ -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
View 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));
}

View File

@ -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)
{
/*

View File

@ -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_ */