2 * Copyright(c) 2019 Intel Corporation
3 * SPDX-License-Identifier: BSD-3-Clause-Clear
11 #define VOL_SIZE 200*1024*1024
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.
17 static int volume_open(ocf_volume_t volume
)
19 const struct ocf_volume_uuid
*uuid
= ocf_volume_get_uuid(volume
);
20 struct myvolume
*myvolume
= ocf_volume_get_priv(volume
);
22 myvolume
->name
= ocf_uuid_to_str(uuid
);
23 myvolume
->mem
= malloc(VOL_SIZE
);
25 printf("VOL OPEN: (name: %s)\n", myvolume
->name
);
31 * In close() function we just free memory allocated in open().
33 static void volume_close(ocf_volume_t volume
)
35 struct myvolume
*myvolume
= ocf_volume_get_priv(volume
);
37 printf("VOL CLOSE: (name: %s)\n", myvolume
->name
);
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.
45 static void volume_submit_io(struct ocf_io
*io
)
47 struct volume_data
*data
;
48 struct myvolume
*myvolume
;
50 data
= ocf_io_get_data(io
);
51 myvolume
= ocf_volume_get_priv(io
->volume
);
53 if (io
->dir
== OCF_WRITE
) {
54 memcpy(myvolume
->mem
+ io
->addr
,
55 data
->ptr
+ data
->offset
, io
->bytes
);
57 memcpy(data
->ptr
+ data
->offset
,
58 myvolume
->mem
+ io
->addr
, io
->bytes
);
61 printf("VOL: (name: %s), IO: (dir: %s, addr: %ld, bytes: %d)\n",
62 myvolume
->name
, io
->dir
== OCF_READ
? "read" : "write",
69 * We don't need to implement submit_flush(). Just complete io with success.
71 static void volume_submit_flush(struct ocf_io
*io
)
77 * We don't need to implement submit_discard(). Just complete io with success.
79 static void volume_submit_discard(struct ocf_io
*io
)
85 * Let's set maximum io size to 128 KiB.
87 static unsigned int volume_get_max_io_size(ocf_volume_t volume
)
95 static uint64_t volume_get_length(ocf_volume_t volume
)
101 * In set_data() we just assing data and offset to io.
103 static int myvolume_io_set_data(struct ocf_io
*io
, ctx_data_t
*data
,
106 struct myvolume_io
*myvolume_io
= ocf_io_get_priv(io
);
108 myvolume_io
->data
= data
;
109 myvolume_io
->offset
= offset
;
115 * In get_data() return data stored in io.
117 static ctx_data_t
*myvolume_io_get_data(struct ocf_io
*io
)
119 struct myvolume_io
*myvolume_io
= ocf_io_get_priv(io
);
121 return myvolume_io
->data
;
125 * This structure contains volume properties. It describes volume
126 * type, which can be later instantiated as backend storage for cache
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
),
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
,
146 .set_data
= myvolume_io_set_data
,
147 .get_data
= myvolume_io_get_data
,
152 * This function registers volume type in OCF context.
153 * It should be called just after context initialization.
155 int volume_init(ocf_ctx_t ocf_ctx
)
157 return ocf_ctx_register_volume_type(ocf_ctx
, VOL_TYPE
,
162 * This function unregisters volume type in OCF context.
163 * It should be called just before context cleanup.
165 void volume_cleanup(ocf_ctx_t ocf_ctx
)
167 ocf_ctx_unregister_volume_type(ocf_ctx
, VOL_TYPE
);