]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/ocf/example/simple/src/volume.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / ocf / example / simple / src / volume.c
1 /*
2 * Copyright(c) 2019 Intel Corporation
3 * SPDX-License-Identifier: BSD-3-Clause-Clear
4 */
5
6 #include <ocf/ocf.h>
7 #include "volume.h"
8 #include "data.h"
9 #include "ctx.h"
10
11 #define VOL_SIZE 200*1024*1024
12
13 /*
14 * In open() function we store uuid data as volume name (for debug messages)
15 * and allocate 200 MiB of memory to simulate backend storage device.
16 */
17 static int volume_open(ocf_volume_t volume)
18 {
19 const struct ocf_volume_uuid *uuid = ocf_volume_get_uuid(volume);
20 struct myvolume *myvolume = ocf_volume_get_priv(volume);
21
22 myvolume->name = ocf_uuid_to_str(uuid);
23 myvolume->mem = malloc(VOL_SIZE);
24
25 printf("VOL OPEN: (name: %s)\n", myvolume->name);
26
27 return 0;
28 }
29
30 /*
31 * In close() function we just free memory allocated in open().
32 */
33 static void volume_close(ocf_volume_t volume)
34 {
35 struct myvolume *myvolume = ocf_volume_get_priv(volume);
36
37 printf("VOL CLOSE: (name: %s)\n", myvolume->name);
38 free(myvolume->mem);
39 }
40
41 /*
42 * In submit_io() function we simulate read or write to backend storage device
43 * by doing memcpy() to or from previously allocated memory buffer.
44 */
45 static void volume_submit_io(struct ocf_io *io)
46 {
47 struct volume_data *data;
48 struct myvolume *myvolume;
49
50 data = ocf_io_get_data(io);
51 myvolume = ocf_volume_get_priv(io->volume);
52
53 if (io->dir == OCF_WRITE) {
54 memcpy(myvolume->mem + io->addr,
55 data->ptr + data->offset, io->bytes);
56 } else {
57 memcpy(data->ptr + data->offset,
58 myvolume->mem + io->addr, io->bytes);
59 }
60
61 printf("VOL: (name: %s), IO: (dir: %s, addr: %ld, bytes: %d)\n",
62 myvolume->name, io->dir == OCF_READ ? "read" : "write",
63 io->addr, io->bytes);
64
65 io->end(io, 0);
66 }
67
68 /*
69 * We don't need to implement submit_flush(). Just complete io with success.
70 */
71 static void volume_submit_flush(struct ocf_io *io)
72 {
73 io->end(io, 0);
74 }
75
76 /*
77 * We don't need to implement submit_discard(). Just complete io with success.
78 */
79 static void volume_submit_discard(struct ocf_io *io)
80 {
81 io->end(io, 0);
82 }
83
84 /*
85 * Let's set maximum io size to 128 KiB.
86 */
87 static unsigned int volume_get_max_io_size(ocf_volume_t volume)
88 {
89 return 128 * 1024;
90 }
91
92 /*
93 * Return volume size.
94 */
95 static uint64_t volume_get_length(ocf_volume_t volume)
96 {
97 return VOL_SIZE;
98 }
99
100 /*
101 * In set_data() we just assing data and offset to io.
102 */
103 static int myvolume_io_set_data(struct ocf_io *io, ctx_data_t *data,
104 uint32_t offset)
105 {
106 struct myvolume_io *myvolume_io = ocf_io_get_priv(io);
107
108 myvolume_io->data = data;
109 myvolume_io->offset = offset;
110
111 return 0;
112 }
113
114 /*
115 * In get_data() return data stored in io.
116 */
117 static ctx_data_t *myvolume_io_get_data(struct ocf_io *io)
118 {
119 struct myvolume_io *myvolume_io = ocf_io_get_priv(io);
120
121 return myvolume_io->data;
122 }
123
124 /*
125 * This structure contains volume properties. It describes volume
126 * type, which can be later instantiated as backend storage for cache
127 * or core.
128 */
129 const struct ocf_volume_properties volume_properties = {
130 .name = "Example volume",
131 .io_priv_size = sizeof(struct myvolume_io),
132 .volume_priv_size = sizeof(struct myvolume),
133 .caps = {
134 .atomic_writes = 0,
135 },
136 .ops = {
137 .open = volume_open,
138 .close = volume_close,
139 .submit_io = volume_submit_io,
140 .submit_flush = volume_submit_flush,
141 .submit_discard = volume_submit_discard,
142 .get_max_io_size = volume_get_max_io_size,
143 .get_length = volume_get_length,
144 },
145 .io_ops = {
146 .set_data = myvolume_io_set_data,
147 .get_data = myvolume_io_get_data,
148 },
149 };
150
151 /*
152 * This function registers volume type in OCF context.
153 * It should be called just after context initialization.
154 */
155 int volume_init(ocf_ctx_t ocf_ctx)
156 {
157 return ocf_ctx_register_volume_type(ocf_ctx, VOL_TYPE,
158 &volume_properties);
159 }
160
161 /*
162 * This function unregisters volume type in OCF context.
163 * It should be called just before context cleanup.
164 */
165 void volume_cleanup(ocf_ctx_t ocf_ctx)
166 {
167 ocf_ctx_unregister_volume_type(ocf_ctx, VOL_TYPE);
168 }