Introduce ocf_io_internal
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
parent
999f3f7245
commit
4d2d31ff76
@ -48,7 +48,7 @@ static void volume_submit_io(struct ocf_io *io)
|
|||||||
struct myvolume *myvolume;
|
struct myvolume *myvolume;
|
||||||
|
|
||||||
data = ocf_io_get_data(io);
|
data = ocf_io_get_data(io);
|
||||||
myvolume = ocf_volume_get_priv(io->volume);
|
myvolume = ocf_volume_get_priv(ocf_io_get_volume(io));
|
||||||
|
|
||||||
if (io->dir == OCF_WRITE) {
|
if (io->dir == OCF_WRITE) {
|
||||||
memcpy(myvolume->mem + io->addr,
|
memcpy(myvolume->mem + io->addr,
|
||||||
|
28
inc/ocf_io.h
28
inc/ocf_io.h
@ -48,16 +48,6 @@ typedef void (*ocf_end_io_t)(struct ocf_io *io, int error);
|
|||||||
* @brief OCF IO main structure
|
* @brief OCF IO main structure
|
||||||
*/
|
*/
|
||||||
struct ocf_io {
|
struct ocf_io {
|
||||||
/**
|
|
||||||
* @brief OCF IO destination volume
|
|
||||||
*/
|
|
||||||
ocf_volume_t volume;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Operations set for this OCF IO
|
|
||||||
*/
|
|
||||||
const struct ocf_io_ops *ops;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief OCF IO destination address
|
* @brief OCF IO destination address
|
||||||
*/
|
*/
|
||||||
@ -237,11 +227,7 @@ static inline void ocf_io_set_handle(struct ocf_io *io, ocf_handle_io_t fn)
|
|||||||
* @retval 0 Data set up successfully
|
* @retval 0 Data set up successfully
|
||||||
* @retval Non-zero Data set up failure
|
* @retval Non-zero Data set up failure
|
||||||
*/
|
*/
|
||||||
static inline int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data,
|
int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data, uint32_t offset);
|
||||||
uint32_t offset)
|
|
||||||
{
|
|
||||||
return io->ops->set_data(io, data, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get data vector from OCF IO
|
* @brief Get data vector from OCF IO
|
||||||
@ -252,10 +238,7 @@ static inline int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data,
|
|||||||
*
|
*
|
||||||
* @return Data vector from IO
|
* @return Data vector from IO
|
||||||
*/
|
*/
|
||||||
static inline ctx_data_t *ocf_io_get_data(struct ocf_io *io)
|
ctx_data_t *ocf_io_get_data(struct ocf_io *io);
|
||||||
{
|
|
||||||
return io->ops->get_data(io);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set queue to which IO should be submitted
|
* @brief Set queue to which IO should be submitted
|
||||||
@ -276,4 +259,11 @@ static inline void ocf_io_set_queue(struct ocf_io *io, ocf_queue_t queue)
|
|||||||
*/
|
*/
|
||||||
void ocf_io_handle(struct ocf_io *io, void *opaque);
|
void ocf_io_handle(struct ocf_io *io, void *opaque);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get volume associated with io
|
||||||
|
*
|
||||||
|
* @param[in] io OCF IO to be handled
|
||||||
|
*/
|
||||||
|
ocf_volume_t ocf_io_get_volume(struct ocf_io *io);
|
||||||
|
|
||||||
#endif /* __OCF_IO_H__ */
|
#endif /* __OCF_IO_H__ */
|
||||||
|
@ -63,7 +63,7 @@ static void metadata_io_read_i_atomic_step_end(struct ocf_io *io, int error)
|
|||||||
{
|
{
|
||||||
struct metadata_io_read_i_atomic_context *context = io->priv1;
|
struct metadata_io_read_i_atomic_context *context = io->priv1;
|
||||||
|
|
||||||
OCF_DEBUG_TRACE(ocf_volume_get_cache(io->volume));
|
OCF_DEBUG_TRACE(ocf_volume_get_cache(ocf_io_get_volume(io)));
|
||||||
|
|
||||||
ocf_io_put(io);
|
ocf_io_put(io);
|
||||||
|
|
||||||
|
@ -165,18 +165,10 @@ static inline void dec_counter_if_req_was_dirty(struct ocf_core_io *core_io,
|
|||||||
|
|
||||||
static inline int ocf_core_validate_io(struct ocf_io *io)
|
static inline int ocf_core_validate_io(struct ocf_io *io)
|
||||||
{
|
{
|
||||||
ocf_core_t core;
|
ocf_volume_t volume = ocf_io_get_volume(io);
|
||||||
|
ocf_core_t core = ocf_volume_to_core(volume);
|
||||||
|
|
||||||
if (!io->volume)
|
if (io->addr + io->bytes > ocf_volume_get_length(volume))
|
||||||
return -OCF_ERR_INVAL;
|
|
||||||
|
|
||||||
if (!io->ops)
|
|
||||||
return -OCF_ERR_INVAL;
|
|
||||||
|
|
||||||
if (io->addr >= ocf_volume_get_length(io->volume))
|
|
||||||
return -OCF_ERR_INVAL;
|
|
||||||
|
|
||||||
if (io->addr + io->bytes > ocf_volume_get_length(io->volume))
|
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
if (io->io_class >= OCF_IO_CLASS_MAX)
|
if (io->io_class >= OCF_IO_CLASS_MAX)
|
||||||
@ -194,7 +186,6 @@ static inline int ocf_core_validate_io(struct ocf_io *io)
|
|||||||
/* Core volume I/O must not be queued on management queue - this would
|
/* Core volume I/O must not be queued on management queue - this would
|
||||||
* break I/O accounting code, resulting in use-after-free type of errors
|
* break I/O accounting code, resulting in use-after-free type of errors
|
||||||
* after cache detach, core remove etc. */
|
* after cache detach, core remove etc. */
|
||||||
core = ocf_volume_to_core(io->volume);
|
|
||||||
if (io->io_queue == ocf_core_get_cache(core)->mngt_queue)
|
if (io->io_queue == ocf_core_get_cache(core)->mngt_queue)
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
@ -234,7 +225,7 @@ void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode)
|
|||||||
|
|
||||||
core_io = ocf_io_to_core_io(io);
|
core_io = ocf_io_to_core_io(io);
|
||||||
|
|
||||||
core = ocf_volume_to_core(io->volume);
|
core = ocf_volume_to_core(ocf_io_get_volume(io));
|
||||||
cache = ocf_core_get_cache(core);
|
cache = ocf_core_get_cache(core);
|
||||||
|
|
||||||
ocf_trace_init_io(core_io, cache);
|
ocf_trace_init_io(core_io, cache);
|
||||||
@ -311,7 +302,7 @@ int ocf_core_submit_io_fast(struct ocf_io *io)
|
|||||||
|
|
||||||
core_io = ocf_io_to_core_io(io);
|
core_io = ocf_io_to_core_io(io);
|
||||||
|
|
||||||
core = ocf_volume_to_core(io->volume);
|
core = ocf_volume_to_core(ocf_io_get_volume(io));
|
||||||
cache = ocf_core_get_cache(core);
|
cache = ocf_core_get_cache(core);
|
||||||
|
|
||||||
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
||||||
@ -413,7 +404,7 @@ static void ocf_core_volume_submit_flush(struct ocf_io *io)
|
|||||||
|
|
||||||
core_io = ocf_io_to_core_io(io);
|
core_io = ocf_io_to_core_io(io);
|
||||||
|
|
||||||
core = ocf_volume_to_core(io->volume);
|
core = ocf_volume_to_core(ocf_io_get_volume(io));
|
||||||
cache = ocf_core_get_cache(core);
|
cache = ocf_core_get_cache(core);
|
||||||
|
|
||||||
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
||||||
@ -455,7 +446,7 @@ static void ocf_core_volume_submit_discard(struct ocf_io *io)
|
|||||||
|
|
||||||
core_io = ocf_io_to_core_io(io);
|
core_io = ocf_io_to_core_io(io);
|
||||||
|
|
||||||
core = ocf_volume_to_core(io->volume);
|
core = ocf_volume_to_core(ocf_io_get_volume(io));
|
||||||
cache = ocf_core_get_cache(core);
|
cache = ocf_core_get_cache(core);
|
||||||
|
|
||||||
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
||||||
|
62
src/ocf_io.c
62
src/ocf_io.c
@ -26,8 +26,8 @@
|
|||||||
* +-------------------------+ <----------------
|
* +-------------------------+ <----------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define OCF_IO_TOTAL_SIZE(priv_size) (sizeof(struct ocf_io_meta) + \
|
#define OCF_IO_TOTAL_SIZE(priv_size) \
|
||||||
sizeof(struct ocf_io) + priv_size)
|
(sizeof(struct ocf_io_internal) + priv_size)
|
||||||
|
|
||||||
env_allocator *ocf_io_allocator_create(uint32_t size, const char *name)
|
env_allocator *ocf_io_allocator_create(uint32_t size, const char *name)
|
||||||
{
|
{
|
||||||
@ -43,35 +43,29 @@ void ocf_io_allocator_destroy(env_allocator *allocator)
|
|||||||
* IO internal API
|
* IO internal API
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *ocf_io_get_meta(struct ocf_io* io)
|
static struct ocf_io_internal *ocf_io_get_internal(struct ocf_io* io)
|
||||||
{
|
{
|
||||||
return (void *)io - sizeof(struct ocf_io_meta);
|
return container_of(io, struct ocf_io_internal, io);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ocf_io *ocf_io_new(ocf_volume_t volume)
|
struct ocf_io *ocf_io_new(ocf_volume_t volume)
|
||||||
{
|
{
|
||||||
struct ocf_io *io;
|
struct ocf_io_internal *ioi;
|
||||||
struct ocf_io_meta *io_meta;
|
|
||||||
void *data;
|
|
||||||
|
|
||||||
if (!ocf_refcnt_inc(&volume->refcnt))
|
if (!ocf_refcnt_inc(&volume->refcnt))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
data = env_allocator_new(volume->type->allocator);
|
ioi = env_allocator_new(volume->type->allocator);
|
||||||
if (!data) {
|
if (!ioi) {
|
||||||
ocf_refcnt_dec(&volume->refcnt);
|
ocf_refcnt_dec(&volume->refcnt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
io = data + sizeof(struct ocf_io_meta);
|
ioi->meta.volume = volume;
|
||||||
|
ioi->meta.ops = &volume->type->properties->io_ops;
|
||||||
|
env_atomic_set(&ioi->meta.ref_count, 1);
|
||||||
|
|
||||||
io_meta = ocf_io_get_meta(io);
|
return &ioi->io;
|
||||||
|
|
||||||
io->volume = volume;
|
|
||||||
io->ops = &volume->type->properties->io_ops;
|
|
||||||
env_atomic_set(&io_meta->ref_count, 1);
|
|
||||||
|
|
||||||
return io;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -83,22 +77,42 @@ void *ocf_io_get_priv(struct ocf_io* io)
|
|||||||
return (void *)io + sizeof(struct ocf_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);
|
||||||
|
|
||||||
|
return ioi->meta.ops->set_data(io, data, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx_data_t *ocf_io_get_data(struct ocf_io *io)
|
||||||
|
{
|
||||||
|
struct ocf_io_internal *ioi = ocf_io_get_internal(io);
|
||||||
|
|
||||||
|
return ioi->meta.ops->get_data(io);
|
||||||
|
}
|
||||||
|
|
||||||
void ocf_io_get(struct ocf_io *io)
|
void ocf_io_get(struct ocf_io *io)
|
||||||
{
|
{
|
||||||
struct ocf_io_meta *io_meta = ocf_io_get_meta(io);
|
struct ocf_io_internal *ioi = ocf_io_get_internal(io);
|
||||||
|
|
||||||
env_atomic_inc_return(&io_meta->ref_count);
|
env_atomic_inc_return(&ioi->meta.ref_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ocf_io_put(struct ocf_io *io)
|
void ocf_io_put(struct ocf_io *io)
|
||||||
{
|
{
|
||||||
struct ocf_io_meta *io_meta = ocf_io_get_meta(io);
|
struct ocf_io_internal *ioi = ocf_io_get_internal(io);
|
||||||
|
|
||||||
if (env_atomic_dec_return(&io_meta->ref_count))
|
if (env_atomic_dec_return(&ioi->meta.ref_count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ocf_refcnt_dec(&io->volume->refcnt);
|
ocf_refcnt_dec(&ioi->meta.volume->refcnt);
|
||||||
|
|
||||||
env_allocator_del(io->volume->type->allocator,
|
env_allocator_del(ioi->meta.volume->type->allocator, (void *)ioi);
|
||||||
(void *)io - sizeof(struct ocf_io_meta));
|
}
|
||||||
|
|
||||||
|
ocf_volume_t ocf_io_get_volume(struct ocf_io *io)
|
||||||
|
{
|
||||||
|
struct ocf_io_internal *ioi = ocf_io_get_internal(io);
|
||||||
|
|
||||||
|
return ioi->meta.volume;
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,17 @@
|
|||||||
#include "ocf_request.h"
|
#include "ocf_request.h"
|
||||||
|
|
||||||
struct ocf_io_meta {
|
struct ocf_io_meta {
|
||||||
|
ocf_volume_t volume;
|
||||||
|
const struct ocf_io_ops *ops;
|
||||||
env_atomic ref_count;
|
env_atomic ref_count;
|
||||||
struct ocf_request *req;
|
struct ocf_request *req;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ocf_io_internal {
|
||||||
|
struct ocf_io_meta meta;
|
||||||
|
struct ocf_io io;
|
||||||
|
};
|
||||||
|
|
||||||
env_allocator *ocf_io_allocator_create(uint32_t size, const char *name);
|
env_allocator *ocf_io_allocator_create(uint32_t size, const char *name);
|
||||||
|
|
||||||
void ocf_io_allocator_destroy(env_allocator *allocator);
|
void ocf_io_allocator_destroy(env_allocator *allocator);
|
||||||
|
@ -234,40 +234,46 @@ struct ocf_io *ocf_volume_new_io(ocf_volume_t volume)
|
|||||||
|
|
||||||
void ocf_volume_submit_io(struct ocf_io *io)
|
void ocf_volume_submit_io(struct ocf_io *io)
|
||||||
{
|
{
|
||||||
ENV_BUG_ON(!io->volume->type->properties->ops.submit_io);
|
ocf_volume_t volume = ocf_io_get_volume(io);
|
||||||
|
|
||||||
if (!io->volume->opened)
|
ENV_BUG_ON(!volume->type->properties->ops.submit_io);
|
||||||
|
|
||||||
|
if (!volume->opened)
|
||||||
io->end(io, -OCF_ERR_IO);
|
io->end(io, -OCF_ERR_IO);
|
||||||
|
|
||||||
io->volume->type->properties->ops.submit_io(io);
|
volume->type->properties->ops.submit_io(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ocf_volume_submit_flush(struct ocf_io *io)
|
void ocf_volume_submit_flush(struct ocf_io *io)
|
||||||
{
|
{
|
||||||
ENV_BUG_ON(!io->volume->type->properties->ops.submit_flush);
|
ocf_volume_t volume = ocf_io_get_volume(io);
|
||||||
|
|
||||||
if (!io->volume->opened)
|
ENV_BUG_ON(!volume->type->properties->ops.submit_flush);
|
||||||
|
|
||||||
|
if (!volume->opened)
|
||||||
io->end(io, -OCF_ERR_IO);
|
io->end(io, -OCF_ERR_IO);
|
||||||
|
|
||||||
if (!io->volume->type->properties->ops.submit_flush) {
|
if (!volume->type->properties->ops.submit_flush) {
|
||||||
ocf_io_end(io, 0);
|
ocf_io_end(io, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
io->volume->type->properties->ops.submit_flush(io);
|
volume->type->properties->ops.submit_flush(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ocf_volume_submit_discard(struct ocf_io *io)
|
void ocf_volume_submit_discard(struct ocf_io *io)
|
||||||
{
|
{
|
||||||
if (!io->volume->opened)
|
ocf_volume_t volume = ocf_io_get_volume(io);
|
||||||
|
|
||||||
|
if (!volume->opened)
|
||||||
io->end(io, -OCF_ERR_IO);
|
io->end(io, -OCF_ERR_IO);
|
||||||
|
|
||||||
if (!io->volume->type->properties->ops.submit_discard) {
|
if (!volume->type->properties->ops.submit_discard) {
|
||||||
ocf_io_end(io, 0);
|
ocf_io_end(io, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
io->volume->type->properties->ops.submit_discard(io);
|
volume->type->properties->ops.submit_discard(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ocf_volume_open(ocf_volume_t volume, void *volume_params)
|
int ocf_volume_open(ocf_volume_t volume, void *volume_params)
|
||||||
|
@ -42,16 +42,20 @@ void ocf_volume_set_uuid(ocf_volume_t volume,
|
|||||||
|
|
||||||
static inline void ocf_volume_submit_metadata(struct ocf_io *io)
|
static inline void ocf_volume_submit_metadata(struct ocf_io *io)
|
||||||
{
|
{
|
||||||
ENV_BUG_ON(!io->volume->type->properties->ops.submit_metadata);
|
ocf_volume_t volume = ocf_io_get_volume(io);
|
||||||
|
|
||||||
io->volume->type->properties->ops.submit_metadata(io);
|
ENV_BUG_ON(!volume->type->properties->ops.submit_metadata);
|
||||||
|
|
||||||
|
volume->type->properties->ops.submit_metadata(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ocf_volume_submit_write_zeroes(struct ocf_io *io)
|
static inline void ocf_volume_submit_write_zeroes(struct ocf_io *io)
|
||||||
{
|
{
|
||||||
ENV_BUG_ON(!io->volume->type->properties->ops.submit_write_zeroes);
|
ocf_volume_t volume = ocf_io_get_volume(io);
|
||||||
|
|
||||||
io->volume->type->properties->ops.submit_write_zeroes(io);
|
ENV_BUG_ON(!volume->type->properties->ops.submit_write_zeroes);
|
||||||
|
|
||||||
|
volume->type->properties->ops.submit_write_zeroes(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /*__OCF_VOLUME_PRIV_H__ */
|
#endif /*__OCF_VOLUME_PRIV_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user