]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/test/lib/blobfs/cache_ut/cache_ut.c
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / spdk / test / lib / blobfs / cache_ut / cache_ut.c
CommitLineData
7c673cae
FG
1/*-
2 * BSD LICENSE
3 *
4 * Copyright (c) Intel Corporation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <stdlib.h>
35#include <unistd.h>
36#include <errno.h>
37#include <stdio.h>
38#include <stdint.h>
39#include <string.h>
40#include <stdbool.h>
41
42#include "spdk/blobfs.h"
43#include "spdk/env.h"
44#include "spdk/log.h"
45#include "spdk/io_channel.h"
46#include "spdk/barrier.h"
47
48#include "spdk_cunit.h"
49#include "lib/blob/bs_dev_common.c"
50#include "lib/test_env.c"
51#include "blobfs.c"
52#include "tree.c"
53
54struct spdk_filesystem *g_fs;
55struct spdk_file *g_file;
56int g_fserrno;
57
58struct spdk_bs_dev g_dev;
59
60struct ut_request {
61 fs_request_fn fn;
62 void *arg;
63 volatile int done;
64 int from_ut;
65};
66
67volatile struct ut_request *g_req = NULL;
68volatile int g_phase = 0;
69
70static void
71send_request(fs_request_fn fn, void *arg)
72{
73 struct ut_request *req;
74
75 req = calloc(1, sizeof(*req));
76 assert(req != NULL);
77 req->fn = fn;
78 req->arg = arg;
79 req->done = 0;
80 req->from_ut = 0;
81 g_req = req;
82 spdk_mb();
83 g_phase = !g_phase;
84 spdk_mb();
85}
86
87static void
88ut_send_request(fs_request_fn fn, void *arg)
89{
90 struct ut_request req;
91
92 req.fn = fn;
93 req.arg = arg;
94 req.done = 0;
95 req.from_ut = 1;
96 g_req = &req;
97 spdk_mb();
98 g_phase = !g_phase;
99 spdk_mb();
100 while (req.done == 0)
101 ;
102}
103
104static void
105fs_op_complete(void *ctx, int fserrno)
106{
107 g_fserrno = fserrno;
108}
109
110static void
111fs_op_with_handle_complete(void *ctx, struct spdk_filesystem *fs, int fserrno)
112{
113 g_fs = fs;
114 g_fserrno = fserrno;
115}
116
117static void
118_fs_init(void *arg)
119{
120 g_fs = NULL;
121 g_fserrno = -1;
122 spdk_fs_init(&g_dev, send_request, fs_op_with_handle_complete, NULL);
123 SPDK_CU_ASSERT_FATAL(g_fs != NULL);
124 CU_ASSERT(g_fserrno == 0);
125}
126
127static void
128_fs_unload(void *arg)
129{
130 g_fserrno = -1;
131 spdk_fs_unload(g_fs, fs_op_complete, NULL);
132 CU_ASSERT(g_fserrno == 0);
133 g_fs = NULL;
134}
135
136static void
137cache_write(void)
138{
139 uint64_t length;
140 int rc;
141 char buf[100];
142 struct spdk_io_channel *channel;
143
144 ut_send_request(_fs_init, NULL);
145
146 spdk_allocate_thread();
147 channel = spdk_fs_alloc_io_channel_sync(g_fs, SPDK_IO_PRIORITY_DEFAULT);
148
149 rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
150 CU_ASSERT(rc == 0);
151 SPDK_CU_ASSERT_FATAL(g_file != NULL);
152
153 length = (4 * 1024 * 1024);
154 spdk_file_truncate(g_file, channel, length);
155
156 spdk_file_write(g_file, channel, buf, 0, sizeof(buf));
157
158 CU_ASSERT(spdk_file_get_length(g_file) == length);
159
160 spdk_file_truncate(g_file, channel, sizeof(buf));
161
162 spdk_file_close(g_file, channel);
163 rc = spdk_fs_delete_file(g_fs, channel, "testfile");
164 CU_ASSERT(rc == 0);
165
166 rc = spdk_fs_delete_file(g_fs, channel, "testfile");
167 CU_ASSERT(rc == -ENOENT);
168
169 spdk_fs_free_io_channel(channel);
170 spdk_free_thread();
171
172 ut_send_request(_fs_unload, NULL);
173}
174
175static void
176cache_append_no_cache(void)
177{
178 int rc;
179 char buf[100];
180 struct spdk_io_channel *channel;
181
182 ut_send_request(_fs_init, NULL);
183
184 spdk_allocate_thread();
185 channel = spdk_fs_alloc_io_channel_sync(g_fs, SPDK_IO_PRIORITY_DEFAULT);
186
187 rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
188 CU_ASSERT(rc == 0);
189 SPDK_CU_ASSERT_FATAL(g_file != NULL);
190
191 spdk_file_write(g_file, channel, buf, 0 * sizeof(buf), sizeof(buf));
192 CU_ASSERT(spdk_file_get_length(g_file) == 1 * sizeof(buf));
193 spdk_file_write(g_file, channel, buf, 1 * sizeof(buf), sizeof(buf));
194 CU_ASSERT(spdk_file_get_length(g_file) == 2 * sizeof(buf));
195 spdk_file_sync(g_file, channel);
196 cache_free_buffers(g_file);
197 spdk_file_write(g_file, channel, buf, 2 * sizeof(buf), sizeof(buf));
198 CU_ASSERT(spdk_file_get_length(g_file) == 3 * sizeof(buf));
199 spdk_file_write(g_file, channel, buf, 3 * sizeof(buf), sizeof(buf));
200 CU_ASSERT(spdk_file_get_length(g_file) == 4 * sizeof(buf));
201 spdk_file_write(g_file, channel, buf, 4 * sizeof(buf), sizeof(buf));
202 CU_ASSERT(spdk_file_get_length(g_file) == 5 * sizeof(buf));
203
204 spdk_file_close(g_file, channel);
205 rc = spdk_fs_delete_file(g_fs, channel, "testfile");
206 CU_ASSERT(rc == 0);
207
208 spdk_fs_free_io_channel(channel);
209 spdk_free_thread();
210
211 ut_send_request(_fs_unload, NULL);
212}
213
214static void
215terminate_spdk_thread(void *arg)
216{
217 spdk_free_thread();
218 pthread_exit(NULL);
219}
220
221static void *
222spdk_thread(void *arg)
223{
224 struct ut_request *req;
225 int phase = 0;
226 spdk_allocate_thread();
227
228 while (1) {
229 spdk_mb();
230 if (phase != g_phase) {
231 req = (void *)g_req;
232 req->fn(req->arg);
233 req->done = 1;
234 spdk_mb();
235 if (!req->from_ut) {
236 free(req);
237 }
238 phase = !phase;
239 }
240 }
241
242 return NULL;
243}
244
245int main(int argc, char **argv)
246{
247 CU_pSuite suite = NULL;
248 pthread_t spdk_tid;
249 unsigned int num_failures;
250
251 if (CU_initialize_registry() != CUE_SUCCESS) {
252 return CU_get_error();
253 }
254
255 suite = CU_add_suite("cache_ut", NULL, NULL);
256 if (suite == NULL) {
257 CU_cleanup_registry();
258 return CU_get_error();
259 }
260
261 if (
262 CU_add_test(suite, "write", cache_write) == NULL ||
263 CU_add_test(suite, "append_no_cache", cache_append_no_cache) == NULL
264 ) {
265 CU_cleanup_registry();
266 return CU_get_error();
267 }
268
269 init_dev(&g_dev);
270 pthread_create(&spdk_tid, NULL, spdk_thread, NULL);
271 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
272 CU_basic_set_mode(CU_BRM_VERBOSE);
273 CU_basic_run_tests();
274 num_failures = CU_get_number_of_failures();
275 CU_cleanup_registry();
276 free(g_dev_buffer);
277 send_request(terminate_spdk_thread, NULL);
278 pthread_join(spdk_tid, NULL);
279 return num_failures;
280}