Bind ocf_io to ocf_request

Signed-off-by: Robert Baldyga <robert.baldyga@huawei.com>
Signed-off-by: Michal Mielewczyk <michal.mielewczyk@huawei.com>
This commit is contained in:
Robert Baldyga 2023-10-13 21:49:52 +02:00 committed by Michal Mielewczyk
parent 7fb6b62825
commit c5741df0ed
8 changed files with 57 additions and 187 deletions

View File

@ -105,42 +105,6 @@ struct ocf_io {
ocf_end_io_t end;
};
/**
* @brief OCF IO operations set structure
*/
struct ocf_io_ops {
/**
* @brief Set up data vector in OCF IO
*
* @param[in] io OCF IO to set up
* @param[in] data Source context data
* @param[in] offset Data offset in source context data
*
* @retval 0 Data set up successfully
* @retval Non-zero Data set up failure
*/
int (*set_data)(struct ocf_io *io, ctx_data_t *data,
uint32_t offset);
/**
* @brief Get context data from OCF IO
*
* @param[in] io OCF IO to get data
*
* @return Data vector from IO
*/
ctx_data_t *(*get_data)(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 Increase reference counter in OCF IO
*
@ -199,8 +163,6 @@ static inline void ocf_io_set_handle(struct ocf_io *io, ocf_handle_io_t fn)
/**
* @brief Set up data vector in OCF IO
*
* @note Wrapper for set up data vector function
*
* @param[in] io OCF IO to set up
* @param[in] data Source data vector
* @param[in] offset Data offset in source data vector
@ -213,14 +175,21 @@ int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data, uint32_t offset);
/**
* @brief Get data vector from OCF IO
*
* @note Wrapper for get data vector function
*
* @param[in] io OCF IO to get data
*
* @return Data vector from IO
*/
ctx_data_t *ocf_io_get_data(struct ocf_io *io);
/**
* @brief Get offset within the data from OCF IO
*
* @param[in] io OCF IO to get data
*
* @return Offset within data
*/
uint32_t ocf_io_get_offset(struct ocf_io *io);
/**
* @brief Handle IO in cache engine
*

View File

@ -221,18 +221,12 @@ struct ocf_volume_properties {
const char *name;
/*!< The name of volume operations */
uint32_t io_priv_size;
/*!< Size of io private context structure */
uint32_t volume_priv_size;
/*!< Size of volume private context structure */
struct ocf_volume_caps caps;
/*!< Volume capabilities */
struct ocf_io_ops io_ops;
/*!< IO operations */
void (*deinit)(void);
/*!< Deinitialize volume type */

View File

@ -419,35 +419,8 @@ static uint64_t ocf_cache_volume_get_byte_length(ocf_volume_t volume)
return ocf_volume_get_length(ocf_cache_get_volume(cache));
}
/* *** IO OPS *** */
static int ocf_cache_io_set_data(struct ocf_io *io,
ctx_data_t *data, uint32_t offset)
{
struct ocf_request *req;
OCF_CHECK_NULL(io);
req = ocf_io_to_req(io);
req->data = data;
req->offset = offset;
return 0;
}
static ctx_data_t *ocf_cache_io_get_data(struct ocf_io *io)
{
struct ocf_request *req;
OCF_CHECK_NULL(io);
req = ocf_io_to_req(io);
return req->data;
}
const struct ocf_volume_properties ocf_cache_volume_properties = {
.name = "OCF_Cache",
.io_priv_size = 0,
.volume_priv_size = sizeof(struct ocf_cache_volume),
.caps = {
.atomic_writes = 0,
@ -463,15 +436,11 @@ const struct ocf_volume_properties ocf_cache_volume_properties = {
.get_max_io_size = ocf_cache_volume_get_max_io_size,
.get_length = ocf_cache_volume_get_byte_length,
},
.io_ops = {
.set_data = ocf_cache_io_set_data,
.get_data = ocf_cache_io_get_data,
},
.deinit = NULL,
};
static int ocf_cache_io_allocator_init(ocf_io_allocator_t allocator,
uint32_t priv_size, const char *name)
const char *name)
{
return 0;
}

View File

@ -447,39 +447,8 @@ static uint64_t ocf_core_volume_get_byte_length(ocf_volume_t volume)
return ocf_volume_get_length(&core->volume);
}
/* *** IO OPS *** */
static int ocf_core_io_set_data(struct ocf_io *io,
ctx_data_t *data, uint32_t offset)
{
struct ocf_request *req;
OCF_CHECK_NULL(io);
if (!data)
return -OCF_ERR_INVAL;
req = ocf_io_to_req(io);
req->data = data;
req->offset = offset;
return 0;
}
static ctx_data_t *ocf_core_io_get_data(struct ocf_io *io)
{
struct ocf_request *req;
OCF_CHECK_NULL(io);
req = ocf_io_to_req(io);
return req->data;
}
const struct ocf_volume_properties ocf_core_volume_properties = {
.name = "OCF_Core",
.io_priv_size = 0, /* Not used - custom allocator */
.volume_priv_size = sizeof(struct ocf_core_volume),
.caps = {
.atomic_writes = 0,
@ -495,15 +464,11 @@ const struct ocf_volume_properties ocf_core_volume_properties = {
.get_max_io_size = ocf_core_volume_get_max_io_size,
.get_length = ocf_core_volume_get_byte_length,
},
.io_ops = {
.set_data = ocf_core_io_set_data,
.get_data = ocf_core_io_get_data,
},
.deinit = NULL,
};
static int ocf_core_io_allocator_init(ocf_io_allocator_t allocator,
uint32_t priv_size, const char *name)
const char *name)
{
return 0;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright(c) 2012-2022 Intel Corporation
* Copyright(c) 2024 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,34 +8,13 @@
#include "ocf_def_priv.h"
#include "ocf_io_priv.h"
#include "ocf_volume_priv.h"
#include "ocf_core_priv.h"
#include "utils/utils_io_allocator.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(priv_size) \
(sizeof(struct ocf_io_internal) + priv_size)
int ocf_io_allocator_default_init(ocf_io_allocator_t allocator,
uint32_t priv_size, const char *name)
const char *name)
{
allocator->priv = env_allocator_create(OCF_IO_TOTAL(priv_size), name,
allocator->priv = env_allocator_create(sizeof(struct ocf_request), name,
true);
if (!allocator->priv)
return -OCF_ERR_NO_MEM;
@ -82,7 +62,7 @@ struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue,
uint64_t addr, uint32_t bytes, uint32_t dir,
uint32_t io_class, uint64_t flags)
{
struct ocf_io_internal *ioi;
struct ocf_request *req;
uint32_t sector_size = SECTORS_TO_BYTES(1);
if ((addr % sector_size) || (bytes % sector_size))
@ -91,76 +71,80 @@ struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue,
if (!ocf_refcnt_inc(&volume->refcnt))
return NULL;
ioi = ocf_io_allocator_new(&volume->type->allocator, volume, queue,
req = ocf_io_allocator_new(&volume->type->allocator, volume, queue,
addr, bytes, dir);
if (!ioi) {
if (!req) {
ocf_refcnt_dec(&volume->refcnt);
return NULL;
}
ioi->meta.volume = volume;
ioi->meta.ops = &volume->type->properties->io_ops;
env_atomic_set(&ioi->meta.ref_count, 1);
req->ioi.meta.volume = volume;
env_atomic_set(&req->ioi.meta.ref_count, 1);
ioi->io.io_queue = queue;
ioi->io.addr = addr;
ioi->io.bytes = bytes;
ioi->io.dir = dir;
ioi->io.io_class = io_class;
ioi->io.flags = flags;
req->ioi.io.io_queue = queue;
req->ioi.io.addr = addr;
req->ioi.io.bytes = bytes;
req->ioi.io.dir = dir;
req->ioi.io.io_class = io_class;
req->ioi.io.flags = flags;
return &ioi->io;
return &req->ioi.io;
}
/*
* IO external API
*/
void *ocf_io_get_priv(struct ocf_io* io)
{
return (void *)io + sizeof(struct ocf_io);
}
int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data, uint32_t offset)
{
struct ocf_io_internal *ioi = ocf_io_get_internal(io);
struct ocf_request *req = ocf_io_to_req(io);
return ioi->meta.ops->set_data(io, data, offset);
req->data = data;
req->offset = offset;
return 0;
}
ctx_data_t *ocf_io_get_data(struct ocf_io *io)
{
struct ocf_io_internal *ioi = ocf_io_get_internal(io);
struct ocf_request *req = ocf_io_to_req(io);
return ioi->meta.ops->get_data(io);
return req->data;
}
uint32_t ocf_io_get_offset(struct ocf_io *io)
{
struct ocf_request *req = ocf_io_to_req(io);
return req->offset;
}
void ocf_io_get(struct ocf_io *io)
{
struct ocf_io_internal *ioi = ocf_io_get_internal(io);
struct ocf_request *req = ocf_io_to_req(io);
env_atomic_inc_return(&ioi->meta.ref_count);
env_atomic_inc_return(&req->ioi.meta.ref_count);
}
void ocf_io_put(struct ocf_io *io)
{
struct ocf_io_internal *ioi = ocf_io_get_internal(io);
struct ocf_request *req = ocf_io_to_req(io);
struct ocf_volume *volume;
if (env_atomic_dec_return(&ioi->meta.ref_count))
if (env_atomic_dec_return(&req->ioi.meta.ref_count))
return;
/* Hold volume reference to avoid use after free of ioi */
volume = ioi->meta.volume;
/* Hold volume reference to avoid use after free of req */
volume = req->ioi.meta.volume;
ocf_io_allocator_del(&ioi->meta.volume->type->allocator, (void *)ioi);
ocf_io_allocator_del(&volume->type->allocator, (void *)req);
ocf_refcnt_dec(&volume->refcnt);
}
ocf_volume_t ocf_io_get_volume(struct ocf_io *io)
{
struct ocf_io_internal *ioi = ocf_io_get_internal(io);
struct ocf_request *req = ocf_io_to_req(io);
return ioi->meta.volume;
return req->ioi.meta.volume;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright(c) 2012-2022 Intel Corporation
* Copyright(c) 2024 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -11,24 +12,17 @@
struct ocf_io_meta {
ocf_volume_t volume;
const struct ocf_io_ops *ops;
env_atomic ref_count;
struct ocf_request *req;
};
struct ocf_io_internal {
struct ocf_io_meta meta;
struct ocf_io io;
};
static inline struct ocf_io_internal *ocf_io_get_internal(struct ocf_io* io)
{
return container_of(io, struct ocf_io_internal, io);
}
int ocf_io_allocator_default_init(ocf_io_allocator_t allocator,
uint32_t priv_size, const char *name);
const char *name);
void ocf_io_allocator_default_deinit(ocf_io_allocator_t allocator);
@ -38,10 +32,6 @@ void *ocf_io_allocator_default_new(ocf_io_allocator_t allocator,
void ocf_io_allocator_default_del(ocf_io_allocator_t allocator, void *obj);
int ocf_io_allocator_init(ocf_io_allocator_t allocator, ocf_io_allocator_type_t type,
uint32_t priv_size, const char *name);
struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue,
uint64_t addr, uint32_t bytes, uint32_t dir,
uint32_t io_class, uint64_t flags);

View File

@ -57,7 +57,7 @@ int ocf_volume_type_init(struct ocf_volume_type **type,
allocator_type = ocf_io_allocator_get_type_default();
ret = ocf_io_allocator_init(&new_type->allocator, allocator_type,
properties->io_priv_size, properties->name);
properties->name);
if (ret)
goto err;

View File

@ -1,5 +1,6 @@
/*
* Copyright(c) 2019-2021 Intel Corporation
* Copyright(c) 2024 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -11,8 +12,7 @@
typedef struct ocf_io_allocator *ocf_io_allocator_t;
struct ocf_io_allocator_ops {
int (*allocator_init)(ocf_io_allocator_t allocator,
uint32_t priv_size, const char *name);
int (*allocator_init)(ocf_io_allocator_t allocator, const char *name);
void (*allocator_deinit)(ocf_io_allocator_t allocator);
void *(*allocator_new)(ocf_io_allocator_t allocator,
ocf_volume_t volume, ocf_queue_t queue,
@ -45,11 +45,10 @@ static inline void ocf_io_allocator_del(ocf_io_allocator_t allocator, void *obj)
}
static inline int ocf_io_allocator_init(ocf_io_allocator_t allocator,
ocf_io_allocator_type_t type, uint32_t size, const char *name)
ocf_io_allocator_type_t type, const char *name)
{
allocator->type = type;
return allocator->type->ops.allocator_init(allocator, size, name);
return allocator->type->ops.allocator_init(allocator, name);
}
static inline void ocf_io_allocator_deinit(ocf_io_allocator_t allocator)