diff --git a/inc/ocf_data_obj.h b/inc/ocf_data_obj.h index 49cf72a..02457c3 100644 --- a/inc/ocf_data_obj.h +++ b/inc/ocf_data_obj.h @@ -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 * diff --git a/inc/ocf_io.h b/inc/ocf_io.h index e64082f..36cfadb 100644 --- a/inc/ocf_io.h +++ b/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 diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index cd902f0..ac0a43d 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -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; diff --git a/src/mngt/ocf_mngt_common.c b/src/mngt/ocf_mngt_common.c index 216f535..aa40ad6 100644 --- a/src/mngt/ocf_mngt_common.c +++ b/src/mngt/ocf_mngt_common.c @@ -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(); diff --git a/src/mngt/ocf_mngt_core.c b/src/mngt/ocf_mngt_core.c index 8174628..a5e1228 100644 --- a/src/mngt/ocf_mngt_core.c +++ b/src/mngt/ocf_mngt_core.c @@ -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, diff --git a/src/ocf_core.c b/src/ocf_core.c index eeadd2c..0364101 100644 --- a/src/ocf_core.c +++ b/src/ocf_core.c @@ -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, }, }; diff --git a/src/ocf_core_priv.h b/src/ocf_core_priv.h index 140060c..a6597ae 100644 --- a/src/ocf_core_priv.h +++ b/src/ocf_core_priv.h @@ -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 */ diff --git a/src/ocf_data_obj.c b/src/ocf_data_obj.c index 780cc9e..63720c5 100644 --- a/src/ocf_data_obj.c +++ b/src/ocf_data_obj.c @@ -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); } diff --git a/src/ocf_data_obj_priv.h b/src/ocf_data_obj_priv.h index 22f374e..90a68dd 100644 --- a/src/ocf_data_obj_priv.h +++ b/src/ocf_data_obj_priv.h @@ -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); diff --git a/src/ocf_io.c b/src/ocf_io.c new file mode 100644 index 0000000..684a40b --- /dev/null +++ b/src/ocf_io.c @@ -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)); +} diff --git a/src/ocf_io_priv.h b/src/ocf_io_priv.h index a95ca5c..c88001c 100644 --- a/src/ocf_io_priv.h +++ b/src/ocf_io_priv.h @@ -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) { /* diff --git a/src/utils/utils_device.h b/src/utils/utils_device.h index 17585f6..3819505 100644 --- a/src/utils/utils_device.h +++ b/src/utils/utils_device.h @@ -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_ */