2 * Copyright(c) 2012-2018 Intel Corporation
3 * SPDX-License-Identifier: BSD-3-Clause-Clear
7 #include "ocf_def_priv.h"
8 #include "ocf_io_priv.h"
9 #include "ocf_volume_priv.h"
10 #include "utils/utils_io_allocator.h"
13 * This is io allocator dedicated for bottom devices.
14 * Out IO structure looks like this:
15 * --------------> +-------------------------+
17 * | of this part. | struct ocf_io_meta |
19 * | +-------------------------+ <----------------
20 * | | | Bottom adapter |
21 * | | struct ocf_io | is aware of |
23 * --------------> +-------------------------+ |
25 * | Bottom adapter specific | |
26 * | context data structure. | |
28 * +-------------------------+ <----------------
31 #define OCF_IO_TOTAL(priv_size) \
32 (sizeof(struct ocf_io_internal) + priv_size)
34 static int ocf_io_allocator_default_init(ocf_io_allocator_t allocator
,
35 uint32_t priv_size
, const char *name
)
37 allocator
->priv
= env_allocator_create(OCF_IO_TOTAL(priv_size
), name
);
39 return -OCF_ERR_NO_MEM
;
44 static void ocf_io_allocator_default_deinit(ocf_io_allocator_t allocator
)
46 env_allocator_destroy(allocator
->priv
);
47 allocator
->priv
= NULL
;
50 static void *ocf_io_allocator_default_new(ocf_io_allocator_t allocator
,
51 ocf_volume_t volume
, ocf_queue_t queue
,
52 uint64_t addr
, uint32_t bytes
, uint32_t dir
)
54 return env_allocator_new(allocator
->priv
);
57 static void ocf_io_allocator_default_del(ocf_io_allocator_t allocator
, void *obj
)
59 env_allocator_del(allocator
->priv
, obj
);
62 const struct ocf_io_allocator_type type_default
= {
64 .allocator_init
= ocf_io_allocator_default_init
,
65 .allocator_deinit
= ocf_io_allocator_default_deinit
,
66 .allocator_new
= ocf_io_allocator_default_new
,
67 .allocator_del
= ocf_io_allocator_default_del
,
71 ocf_io_allocator_type_t
ocf_io_allocator_get_type_default(void)
80 static struct ocf_io_internal
*ocf_io_get_internal(struct ocf_io
* io
)
82 return container_of(io
, struct ocf_io_internal
, io
);
85 struct ocf_io
*ocf_io_new(ocf_volume_t volume
, ocf_queue_t queue
,
86 uint64_t addr
, uint32_t bytes
, uint32_t dir
,
87 uint32_t io_class
, uint64_t flags
)
89 struct ocf_io_internal
*ioi
;
90 uint32_t sector_size
= SECTORS_TO_BYTES(1);
92 if ((addr
% sector_size
) || (bytes
% sector_size
))
95 if (!ocf_refcnt_inc(&volume
->refcnt
))
98 ioi
= ocf_io_allocator_new(&volume
->type
->allocator
, volume
, queue
,
101 ocf_refcnt_dec(&volume
->refcnt
);
105 ioi
->meta
.volume
= volume
;
106 ioi
->meta
.ops
= &volume
->type
->properties
->io_ops
;
107 env_atomic_set(&ioi
->meta
.ref_count
, 1);
109 ioi
->io
.io_queue
= queue
;
111 ioi
->io
.bytes
= bytes
;
113 ioi
->io
.io_class
= io_class
;
114 ioi
->io
.flags
= flags
;
123 void *ocf_io_get_priv(struct ocf_io
* io
)
125 return (void *)io
+ sizeof(struct ocf_io
);
128 int ocf_io_set_data(struct ocf_io
*io
, ctx_data_t
*data
, uint32_t offset
)
130 struct ocf_io_internal
*ioi
= ocf_io_get_internal(io
);
132 return ioi
->meta
.ops
->set_data(io
, data
, offset
);
135 ctx_data_t
*ocf_io_get_data(struct ocf_io
*io
)
137 struct ocf_io_internal
*ioi
= ocf_io_get_internal(io
);
139 return ioi
->meta
.ops
->get_data(io
);
142 void ocf_io_get(struct ocf_io
*io
)
144 struct ocf_io_internal
*ioi
= ocf_io_get_internal(io
);
146 env_atomic_inc_return(&ioi
->meta
.ref_count
);
149 void ocf_io_put(struct ocf_io
*io
)
151 struct ocf_io_internal
*ioi
= ocf_io_get_internal(io
);
153 if (env_atomic_dec_return(&ioi
->meta
.ref_count
))
156 ocf_refcnt_dec(&ioi
->meta
.volume
->refcnt
);
158 ocf_io_allocator_del(&ioi
->meta
.volume
->type
->allocator
, (void *)ioi
);
161 ocf_volume_t
ocf_io_get_volume(struct ocf_io
*io
)
163 struct ocf_io_internal
*ioi
= ocf_io_get_internal(io
);
165 return ioi
->meta
.volume
;