
Signed-off-by: Robert Baldyga <robert.baldyga@huawei.com> Signed-off-by: Michal Mielewczyk <michal.mielewczyk@huawei.com>
180 lines
3.5 KiB
C
180 lines
3.5 KiB
C
/*
|
|
* Copyright(c) 2012-2022 Intel Corporation
|
|
* Copyright(c) 2024 Huawei Technologies
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "ocf/ocf.h"
|
|
#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"
|
|
|
|
int ocf_io_allocator_default_init(ocf_io_allocator_t allocator,
|
|
const char *name)
|
|
{
|
|
allocator->priv = env_allocator_create(sizeof(struct ocf_request), name,
|
|
true);
|
|
if (!allocator->priv)
|
|
return -OCF_ERR_NO_MEM;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void ocf_io_allocator_default_deinit(ocf_io_allocator_t allocator)
|
|
{
|
|
env_allocator_destroy(allocator->priv);
|
|
allocator->priv = NULL;
|
|
}
|
|
|
|
void *ocf_io_allocator_default_new(ocf_io_allocator_t allocator,
|
|
ocf_volume_t volume, ocf_queue_t queue,
|
|
uint64_t addr, uint32_t bytes, uint32_t dir)
|
|
{
|
|
struct ocf_request *req;
|
|
|
|
req = env_allocator_new(allocator->priv);
|
|
if (!req)
|
|
return NULL;
|
|
|
|
req->io_queue = queue;
|
|
req->addr = addr;
|
|
req->bytes = bytes;
|
|
req->rw = dir;
|
|
|
|
return req;
|
|
}
|
|
|
|
void ocf_io_allocator_default_del(ocf_io_allocator_t allocator, void *obj)
|
|
{
|
|
env_allocator_del(allocator->priv, obj);
|
|
}
|
|
|
|
const struct ocf_io_allocator_type type_default = {
|
|
.ops = {
|
|
.allocator_init = ocf_io_allocator_default_init,
|
|
.allocator_deinit = ocf_io_allocator_default_deinit,
|
|
.allocator_new = ocf_io_allocator_default_new,
|
|
.allocator_del = ocf_io_allocator_default_del,
|
|
},
|
|
};
|
|
|
|
ocf_io_allocator_type_t ocf_io_allocator_get_type_default(void)
|
|
{
|
|
return &type_default;
|
|
}
|
|
|
|
/*
|
|
* IO internal API
|
|
*/
|
|
|
|
ocf_io_t 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_request *req;
|
|
uint32_t sector_size = SECTORS_TO_BYTES(1);
|
|
|
|
if ((addr % sector_size) || (bytes % sector_size))
|
|
return NULL;
|
|
|
|
if (!ocf_refcnt_inc(&volume->refcnt))
|
|
return NULL;
|
|
|
|
req = ocf_io_allocator_new(&volume->type->allocator, volume, queue,
|
|
addr, bytes, dir);
|
|
if (!req) {
|
|
ocf_refcnt_dec(&volume->refcnt);
|
|
return NULL;
|
|
}
|
|
|
|
env_atomic_set(&req->io.ref_count, 1);
|
|
req->io.volume = volume;
|
|
req->io.io_class = io_class;
|
|
req->flags = flags;
|
|
|
|
return req;
|
|
}
|
|
|
|
/*
|
|
* IO external API
|
|
*/
|
|
|
|
int ocf_io_set_data(ocf_io_t io, ctx_data_t *data, uint32_t offset)
|
|
{
|
|
struct ocf_request *req = ocf_io_to_req(io);
|
|
|
|
req->data = data;
|
|
req->offset = offset;
|
|
|
|
return 0;
|
|
}
|
|
|
|
ctx_data_t *ocf_io_get_data(ocf_io_t io)
|
|
{
|
|
struct ocf_request *req = ocf_io_to_req(io);
|
|
|
|
return req->data;
|
|
}
|
|
|
|
uint32_t ocf_io_get_offset(ocf_io_t io)
|
|
{
|
|
struct ocf_request *req = ocf_io_to_req(io);
|
|
|
|
return req->offset;
|
|
}
|
|
|
|
void ocf_io_get(ocf_io_t io)
|
|
{
|
|
struct ocf_request *req = ocf_io_to_req(io);
|
|
|
|
env_atomic_inc_return(&req->io.ref_count);
|
|
}
|
|
|
|
void ocf_io_put(ocf_io_t io)
|
|
{
|
|
struct ocf_request *req = ocf_io_to_req(io);
|
|
struct ocf_volume *volume;
|
|
|
|
if (env_atomic_dec_return(&req->io.ref_count))
|
|
return;
|
|
|
|
volume = req->io.volume;
|
|
|
|
ocf_io_allocator_del(&volume->type->allocator, (void *)req);
|
|
|
|
ocf_refcnt_dec(&volume->refcnt);
|
|
}
|
|
|
|
ocf_volume_t ocf_io_get_volume(ocf_io_t io)
|
|
{
|
|
struct ocf_request *req = ocf_io_to_req(io);
|
|
|
|
return req->io.volume;
|
|
}
|
|
|
|
void ocf_io_set_cmpl(ocf_io_t io, void *context,
|
|
void *context2, ocf_end_io_t fn)
|
|
{
|
|
struct ocf_request *req = ocf_io_to_req(io);
|
|
|
|
req->io.priv1 = context;
|
|
req->io.priv2 = context2;
|
|
req->io.end = fn;
|
|
}
|
|
|
|
void ocf_io_set_start(ocf_io_t io, ocf_start_io_t fn)
|
|
{
|
|
struct ocf_request *req = ocf_io_to_req(io);
|
|
|
|
req->io.start = fn;
|
|
}
|
|
|
|
void ocf_io_set_handle(ocf_io_t io, ocf_handle_io_t fn)
|
|
{
|
|
struct ocf_request *req = ocf_io_to_req(io);
|
|
|
|
req->io.handle = fn;
|
|
}
|