Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2016 Intel Corporation.
3 : : * All rights reserved.
4 : : * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5 : : */
6 : :
7 : : #include "spdk/stdinc.h"
8 : :
9 : : #include "spdk_internal/cunit.h"
10 : :
11 : : #include "reduce/reduce.c"
12 : : #include "spdk_internal/mock.h"
13 : : #define UNIT_TEST_NO_VTOPHYS
14 : : #include "common/lib/test_env.c"
15 : : #undef UNIT_TEST_NO_VTOPHYS
16 : :
17 : : static struct spdk_reduce_vol *g_vol;
18 : : static int g_reduce_errno;
19 : : static char *g_volatile_pm_buf;
20 : : static size_t g_volatile_pm_buf_len;
21 : : static char *g_persistent_pm_buf;
22 : : static size_t g_persistent_pm_buf_len;
23 : : static char *g_backing_dev_buf;
24 : : static char g_path[REDUCE_PATH_MAX];
25 : : static char *g_decomp_buf;
26 : : static int g_decompressed_len;
27 : :
28 : : #define TEST_MD_PATH "/tmp"
29 : :
30 : : uint64_t
31 : 41490 : spdk_vtophys(const void *buf, uint64_t *size)
32 : : {
33 : : /* add + 1 to buf addr for cases where buf is the start of the page, that will give us correct end of the page */
34 [ + - + - ]: 41490 : const uint8_t *page_2mb_end = (const uint8_t *)SPDK_ALIGN_CEIL((uintptr_t)buf + 1, VALUE_2MB);
35 : 41490 : uint64_t bytes_to_page_end = page_2mb_end - (const uint8_t *)buf;
36 : 13830 : uint64_t _size;
37 : :
38 [ + - - + ]: 41490 : if (*size) {
39 [ + - ]: 41490 : _size = *size;
40 [ + + ]: 41490 : _size = spdk_min(_size, bytes_to_page_end);
41 [ + - ]: 41490 : *size = _size;
42 : 13830 : }
43 : :
44 : 55320 : return (uintptr_t)buf;
45 : 13830 : }
46 : :
47 : : enum ut_reduce_bdev_io_type {
48 : : UT_REDUCE_IO_READV = 1,
49 : : UT_REDUCE_IO_WRITEV = 2,
50 : : UT_REDUCE_IO_UNMAP = 3,
51 : : };
52 : :
53 : : struct ut_reduce_bdev_io {
54 : : enum ut_reduce_bdev_io_type type;
55 : : struct spdk_reduce_backing_dev *backing_dev;
56 : : struct iovec *iov;
57 : : int iovcnt;
58 : : uint64_t lba;
59 : : uint32_t lba_count;
60 : : struct spdk_reduce_vol_cb_args *args;
61 : : TAILQ_ENTRY(ut_reduce_bdev_io) link;
62 : : };
63 : :
64 : : static bool g_defer_bdev_io = false;
65 : : static TAILQ_HEAD(, ut_reduce_bdev_io) g_pending_bdev_io =
66 : : TAILQ_HEAD_INITIALIZER(g_pending_bdev_io);
67 : : static uint32_t g_pending_bdev_io_count = 0;
68 : :
69 : : static void
70 : 120 : sync_pm_buf(const void *addr, size_t length)
71 : : {
72 : 120 : uint64_t offset = (char *)addr - g_volatile_pm_buf;
73 : :
74 [ + + + + : 120 : memcpy(&g_persistent_pm_buf[offset], addr, length);
+ - ]
75 : 120 : }
76 : :
77 : : int
78 : 0 : pmem_msync(const void *addr, size_t length)
79 : : {
80 : 0 : sync_pm_buf(addr, length);
81 : 0 : return 0;
82 : : }
83 : :
84 : : void
85 : 40 : pmem_persist(const void *addr, size_t len)
86 : : {
87 : 120 : sync_pm_buf(addr, len);
88 : 120 : }
89 : :
90 : : static void
91 : 3 : get_pm_file_size(void)
92 : : {
93 : 2 : struct spdk_reduce_vol_params params;
94 : 1 : uint64_t pm_size, expected_pm_size;
95 : :
96 [ + - ]: 3 : params.backing_io_unit_size = 4096;
97 [ + - ]: 3 : params.chunk_size = 4096 * 4;
98 [ + - ]: 3 : params.vol_size = 4096 * 4 * 100;
99 : :
100 : 3 : pm_size = _get_pm_file_size(¶ms);
101 : 3 : expected_pm_size = sizeof(struct spdk_reduce_vol_superblock);
102 : : /* 100 chunks in logical map * 8 bytes per chunk */
103 : 3 : expected_pm_size += 100 * sizeof(uint64_t);
104 : : /* 100 chunks * (chunk struct size + 4 backing io units per chunk * 8 bytes per backing io unit) */
105 : 3 : expected_pm_size += 100 * (sizeof(struct spdk_reduce_chunk_map) + 4 * sizeof(uint64_t));
106 : : /* reduce allocates some extra chunks too for in-flight writes when logical map
107 : : * is full. REDUCE_EXTRA_CHUNKS is a private #ifdef in reduce.c Here we need the num chunks
108 : : * times (chunk struct size + 4 backing io units per chunk * 8 bytes per backing io unit).
109 : : */
110 : 3 : expected_pm_size += REDUCE_NUM_EXTRA_CHUNKS *
111 : : (sizeof(struct spdk_reduce_chunk_map) + 4 * sizeof(uint64_t));
112 : : /* reduce will add some padding so numbers may not match exactly. Make sure
113 : : * they are close though.
114 : : */
115 : 3 : CU_ASSERT((pm_size - expected_pm_size) <= REDUCE_PM_SIZE_ALIGNMENT);
116 : 3 : }
117 : :
118 : : static void
119 : 3 : get_vol_size(void)
120 : : {
121 : 1 : uint64_t chunk_size, backing_dev_size;
122 : :
123 : 3 : chunk_size = 16 * 1024;
124 : 3 : backing_dev_size = 16 * 1024 * 1000;
125 : 3 : CU_ASSERT(_get_vol_size(chunk_size, backing_dev_size) < backing_dev_size);
126 : 3 : }
127 : :
128 : : void *
129 : 23 : pmem_map_file(const char *path, size_t len, int flags, mode_t mode,
130 : : size_t *mapped_lenp, int *is_pmemp)
131 : : {
132 : 69 : CU_ASSERT(g_volatile_pm_buf == NULL);
133 [ - + ]: 69 : snprintf(g_path, sizeof(g_path), "%s", path);
134 [ + - ]: 69 : *is_pmemp = 1;
135 : :
136 [ + + ]: 69 : if (g_persistent_pm_buf == NULL) {
137 : 42 : g_persistent_pm_buf = calloc(1, len);
138 : 42 : g_persistent_pm_buf_len = len;
139 [ + + # # ]: 42 : SPDK_CU_ASSERT_FATAL(g_persistent_pm_buf != NULL);
140 : 14 : }
141 : :
142 [ + - ]: 69 : *mapped_lenp = g_persistent_pm_buf_len;
143 : 69 : g_volatile_pm_buf = calloc(1, g_persistent_pm_buf_len);
144 [ + + # # ]: 69 : SPDK_CU_ASSERT_FATAL(g_volatile_pm_buf != NULL);
145 [ + + + + ]: 69 : memcpy(g_volatile_pm_buf, g_persistent_pm_buf, g_persistent_pm_buf_len);
146 : 69 : g_volatile_pm_buf_len = g_persistent_pm_buf_len;
147 : :
148 : 69 : return g_volatile_pm_buf;
149 : : }
150 : :
151 : : int
152 : 23 : pmem_unmap(void *addr, size_t len)
153 : : {
154 : 69 : CU_ASSERT(addr == g_volatile_pm_buf);
155 : 69 : CU_ASSERT(len == g_volatile_pm_buf_len);
156 : 69 : free(g_volatile_pm_buf);
157 : 69 : g_volatile_pm_buf = NULL;
158 : 69 : g_volatile_pm_buf_len = 0;
159 : :
160 : 69 : return 0;
161 : : }
162 : :
163 : : static void
164 : 42 : persistent_pm_buf_destroy(void)
165 : : {
166 : 42 : CU_ASSERT(g_persistent_pm_buf != NULL);
167 : 42 : free(g_persistent_pm_buf);
168 : 42 : g_persistent_pm_buf = NULL;
169 : 42 : g_persistent_pm_buf_len = 0;
170 : 42 : }
171 : :
172 : : static void
173 : 3 : unlink_cb(void)
174 : : {
175 : 3 : persistent_pm_buf_destroy();
176 : 3 : }
177 : :
178 : : static void
179 : 48 : init_cb(void *cb_arg, struct spdk_reduce_vol *vol, int reduce_errno)
180 : : {
181 : 48 : g_vol = vol;
182 : 48 : g_reduce_errno = reduce_errno;
183 : 48 : }
184 : :
185 : : static void
186 : 30 : load_cb(void *cb_arg, struct spdk_reduce_vol *vol, int reduce_errno)
187 : : {
188 : 30 : g_vol = vol;
189 : 30 : g_reduce_errno = reduce_errno;
190 : 30 : }
191 : :
192 : : static void
193 : 69 : unload_cb(void *cb_arg, int reduce_errno)
194 : : {
195 : 69 : g_reduce_errno = reduce_errno;
196 : 69 : }
197 : :
198 : : static void
199 : 3 : init_failure(void)
200 : : {
201 : 3 : struct spdk_reduce_vol_params params = {};
202 : 3 : struct spdk_reduce_backing_dev backing_dev = {};
203 : :
204 [ + - ]: 3 : backing_dev.blocklen = 512;
205 : : /* This blockcnt is too small for a reduce vol - there needs to be
206 : : * enough space for at least REDUCE_NUM_EXTRA_CHUNKS + 1 chunks.
207 : : */
208 [ + - ]: 3 : backing_dev.blockcnt = 20;
209 : :
210 [ + - ]: 3 : params.vol_size = 0;
211 [ + - ]: 3 : params.chunk_size = 16 * 1024;
212 [ + - + - ]: 3 : params.backing_io_unit_size = backing_dev.blocklen;
213 [ + - ]: 3 : params.logical_block_size = 512;
214 : :
215 : : /* backing_dev has an invalid size. This should fail. */
216 : 3 : g_vol = NULL;
217 : 3 : g_reduce_errno = 0;
218 : 3 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
219 : 3 : CU_ASSERT(g_reduce_errno == -EINVAL);
220 [ + + # # ]: 3 : SPDK_CU_ASSERT_FATAL(g_vol == NULL);
221 : :
222 : : /* backing_dev now has valid size, but backing_dev still has null
223 : : * function pointers. This should fail.
224 : : */
225 [ + - ]: 3 : backing_dev.blockcnt = 20000;
226 : :
227 : 3 : g_vol = NULL;
228 : 3 : g_reduce_errno = 0;
229 : 3 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
230 : 3 : CU_ASSERT(g_reduce_errno == -EINVAL);
231 [ + + # # ]: 3 : SPDK_CU_ASSERT_FATAL(g_vol == NULL);
232 : 3 : }
233 : :
234 : : static void
235 : 816 : backing_dev_readv_execute(struct spdk_reduce_backing_dev *backing_dev,
236 : : struct iovec *iov, int iovcnt,
237 : : uint64_t lba, uint32_t lba_count,
238 : : struct spdk_reduce_vol_cb_args *args)
239 : : {
240 : 272 : char *offset;
241 : 272 : int i;
242 : :
243 [ + - + - : 816 : offset = g_backing_dev_buf + lba * backing_dev->blocklen;
+ - ]
244 [ + + + - ]: 1665 : for (i = 0; i < iovcnt; i++) {
245 [ + + + + : 849 : memcpy(iov[i].iov_base, offset, iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
246 [ + - + - : 849 : offset += iov[i].iov_len;
+ - + - ]
247 : 283 : }
248 [ + - + - : 816 : args->cb_fn(args->cb_arg, 0);
- + + - +
- + - ]
249 : 816 : }
250 : :
251 : : static void
252 : 12 : backing_dev_insert_io(enum ut_reduce_bdev_io_type type, struct spdk_reduce_backing_dev *backing_dev,
253 : : struct iovec *iov, int iovcnt, uint64_t lba, uint32_t lba_count,
254 : : struct spdk_reduce_vol_cb_args *args)
255 : : {
256 : 4 : struct ut_reduce_bdev_io *ut_bdev_io;
257 : :
258 : 12 : ut_bdev_io = calloc(1, sizeof(*ut_bdev_io));
259 [ + + # # ]: 12 : SPDK_CU_ASSERT_FATAL(ut_bdev_io != NULL);
260 : :
261 [ + - + - ]: 12 : ut_bdev_io->type = type;
262 [ + - + - ]: 12 : ut_bdev_io->backing_dev = backing_dev;
263 [ + - + - ]: 12 : ut_bdev_io->iov = iov;
264 [ + - + - ]: 12 : ut_bdev_io->iovcnt = iovcnt;
265 [ + - + - ]: 12 : ut_bdev_io->lba = lba;
266 [ + - + - ]: 12 : ut_bdev_io->lba_count = lba_count;
267 [ + - + - ]: 12 : ut_bdev_io->args = args;
268 [ + - + - : 12 : TAILQ_INSERT_TAIL(&g_pending_bdev_io, ut_bdev_io, link);
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
269 : 12 : g_pending_bdev_io_count++;
270 : 12 : }
271 : :
272 : : static void
273 : 816 : backing_dev_readv(struct spdk_reduce_backing_dev *backing_dev, struct iovec *iov, int iovcnt,
274 : : uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args)
275 : : {
276 [ + + + + ]: 816 : if (g_defer_bdev_io == false) {
277 : 813 : CU_ASSERT(g_pending_bdev_io_count == 0);
278 : 813 : CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io));
279 : 813 : backing_dev_readv_execute(backing_dev, iov, iovcnt, lba, lba_count, args);
280 : 813 : return;
281 : : }
282 : :
283 : 3 : backing_dev_insert_io(UT_REDUCE_IO_READV, backing_dev, iov, iovcnt, lba, lba_count, args);
284 : 272 : }
285 : :
286 : : static void
287 : 162 : backing_dev_writev_execute(struct spdk_reduce_backing_dev *backing_dev,
288 : : struct iovec *iov, int iovcnt,
289 : : uint64_t lba, uint32_t lba_count,
290 : : struct spdk_reduce_vol_cb_args *args)
291 : : {
292 : 54 : char *offset;
293 : 54 : int i;
294 : :
295 [ + - + - : 162 : offset = g_backing_dev_buf + lba * backing_dev->blocklen;
+ - ]
296 [ + + + - ]: 324 : for (i = 0; i < iovcnt; i++) {
297 [ + + + + : 162 : memcpy(offset, iov[i].iov_base, iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
298 [ + - + - : 162 : offset += iov[i].iov_len;
+ - + - ]
299 : 54 : }
300 [ + - + - : 162 : args->cb_fn(args->cb_arg, 0);
- + + - +
- + - ]
301 : 162 : }
302 : :
303 : : static void
304 : 162 : backing_dev_writev(struct spdk_reduce_backing_dev *backing_dev, struct iovec *iov, int iovcnt,
305 : : uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args)
306 : : {
307 [ + + + + ]: 162 : if (g_defer_bdev_io == false) {
308 : 153 : CU_ASSERT(g_pending_bdev_io_count == 0);
309 : 153 : CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io));
310 : 153 : backing_dev_writev_execute(backing_dev, iov, iovcnt, lba, lba_count, args);
311 : 153 : return;
312 : : }
313 : :
314 : 9 : backing_dev_insert_io(UT_REDUCE_IO_WRITEV, backing_dev, iov, iovcnt, lba, lba_count, args);
315 : 54 : }
316 : :
317 : : static void
318 : 0 : backing_dev_unmap_execute(struct spdk_reduce_backing_dev *backing_dev,
319 : : uint64_t lba, uint32_t lba_count,
320 : : struct spdk_reduce_vol_cb_args *args)
321 : : {
322 : 0 : char *offset;
323 : :
324 [ # # # # : 0 : offset = g_backing_dev_buf + lba * backing_dev->blocklen;
# # ]
325 [ # # # # : 0 : memset(offset, 0, lba_count * backing_dev->blocklen);
# # ]
326 [ # # # # : 0 : args->cb_fn(args->cb_arg, 0);
# # # # #
# # # ]
327 : 0 : }
328 : :
329 : : static void
330 : 0 : backing_dev_unmap(struct spdk_reduce_backing_dev *backing_dev,
331 : : uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args)
332 : : {
333 [ # # # # ]: 0 : if (g_defer_bdev_io == false) {
334 : 0 : CU_ASSERT(g_pending_bdev_io_count == 0);
335 : 0 : CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io));
336 : 0 : backing_dev_unmap_execute(backing_dev, lba, lba_count, args);
337 : 0 : return;
338 : : }
339 : :
340 : 0 : backing_dev_insert_io(UT_REDUCE_IO_UNMAP, backing_dev, NULL, 0, lba, lba_count, args);
341 : 0 : }
342 : :
343 : : static void
344 : 6 : backing_dev_io_execute(uint32_t count)
345 : : {
346 : 2 : struct ut_reduce_bdev_io *ut_bdev_io;
347 : 6 : uint32_t done = 0;
348 : :
349 [ + + ]: 6 : CU_ASSERT(g_defer_bdev_io == true);
350 [ + + + - : 22 : while (!TAILQ_EMPTY(&g_pending_bdev_io) && (count == 0 || done < count)) {
+ + ]
351 : 12 : ut_bdev_io = TAILQ_FIRST(&g_pending_bdev_io);
352 [ + + + - : 12 : TAILQ_REMOVE(&g_pending_bdev_io, ut_bdev_io, link);
+ - - + #
# # # # #
# # # # #
# # # # #
# # + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
353 : 12 : g_pending_bdev_io_count--;
354 [ + + + - : 12 : switch (ut_bdev_io->type) {
- + + - ]
355 : 2 : case UT_REDUCE_IO_READV:
356 [ + - + - ]: 4 : backing_dev_readv_execute(ut_bdev_io->backing_dev,
357 [ + - + - : 1 : ut_bdev_io->iov, ut_bdev_io->iovcnt,
+ - + - ]
358 [ + - + - : 1 : ut_bdev_io->lba, ut_bdev_io->lba_count,
+ - + - ]
359 [ + - + - ]: 1 : ut_bdev_io->args);
360 : 3 : break;
361 : 6 : case UT_REDUCE_IO_WRITEV:
362 [ + - + - ]: 12 : backing_dev_writev_execute(ut_bdev_io->backing_dev,
363 [ + - + - : 3 : ut_bdev_io->iov, ut_bdev_io->iovcnt,
+ - + - ]
364 [ + - + - : 3 : ut_bdev_io->lba, ut_bdev_io->lba_count,
+ - + - ]
365 [ + - + - ]: 3 : ut_bdev_io->args);
366 : 9 : break;
367 : 0 : case UT_REDUCE_IO_UNMAP:
368 [ # # # # ]: 0 : backing_dev_unmap_execute(ut_bdev_io->backing_dev,
369 [ # # # # : 0 : ut_bdev_io->lba, ut_bdev_io->lba_count,
# # # # ]
370 [ # # # # ]: 0 : ut_bdev_io->args);
371 : 0 : break;
372 : 0 : default:
373 : 0 : CU_ASSERT(false);
374 : 0 : break;
375 : : }
376 : 12 : free(ut_bdev_io);
377 : 12 : done++;
378 : : }
379 : 6 : }
380 : :
381 : : static int
382 : 51 : ut_compress(char *outbuf, uint32_t *compressed_len, char *inbuf, uint32_t inbuflen)
383 : : {
384 : 51 : uint32_t len = 0;
385 : 17 : uint8_t count;
386 : 17 : char last;
387 : :
388 : 37484 : while (true) {
389 [ + + ]: 112452 : if (inbuflen == 0) {
390 [ - + ]: 36 : *compressed_len = len;
391 : 36 : return 0;
392 : : }
393 : :
394 [ + + + + ]: 112416 : if (*compressed_len < (len + 2)) {
395 : 15 : return -ENOSPC;
396 : : }
397 : :
398 [ + - ]: 112401 : last = *inbuf;
399 : 112401 : count = 1;
400 : 112401 : inbuflen--;
401 [ + - ]: 112401 : inbuf++;
402 : :
403 [ + + + + : 554493 : while (inbuflen > 0 && *inbuf == last && count < UINT8_MAX) {
+ + + + ]
404 : 442092 : count++;
405 : 442092 : inbuflen--;
406 [ + - ]: 442092 : inbuf++;
407 : : }
408 : :
409 [ + - + - ]: 112401 : outbuf[len] = count;
410 [ + - + - ]: 112401 : outbuf[len + 1] = last;
411 : 112401 : len += 2;
412 : : }
413 : 17 : }
414 : :
415 : : static int
416 : 792 : ut_decompress(uint8_t *outbuf, uint32_t *compressed_len, uint8_t *inbuf, uint32_t inbuflen)
417 : : {
418 : 792 : uint32_t len = 0;
419 : :
420 [ + - + - : 792 : SPDK_CU_ASSERT_FATAL(inbuflen % 2 == 0);
# # ]
421 : :
422 : 19799 : while (true) {
423 [ + + ]: 59397 : if (inbuflen == 0) {
424 [ + - ]: 792 : *compressed_len = len;
425 : 792 : return 0;
426 : : }
427 : :
428 [ + + + - : 58605 : if ((len + inbuf[0]) > *compressed_len) {
+ - - + ]
429 : 0 : return -ENOSPC;
430 : : }
431 : :
432 [ + + + - : 58605 : memset(outbuf, inbuf[1], inbuf[0]);
+ - + - +
- ]
433 [ + - + - : 58605 : outbuf += inbuf[0];
+ - ]
434 [ + - + - ]: 58605 : len += inbuf[0];
435 : 58605 : inbuflen -= 2;
436 [ + - ]: 58605 : inbuf += 2;
437 : : }
438 : 264 : }
439 : :
440 : : static void
441 : 12 : ut_build_data_buffer(uint8_t *data, uint32_t data_len, uint8_t init_val, uint32_t repeat)
442 : : {
443 : 12 : uint32_t _repeat = repeat;
444 : :
445 [ + + # # ]: 12 : SPDK_CU_ASSERT_FATAL(repeat > 0);
446 : :
447 [ + + ]: 122892 : while (data_len > 0) {
448 [ + - ]: 122880 : *data = init_val;
449 [ + - ]: 122880 : data++;
450 : 122880 : data_len--;
451 : 122880 : _repeat--;
452 [ + + ]: 122880 : if (_repeat == 0) {
453 : 110595 : init_val++;
454 : 110595 : _repeat = repeat;
455 : 36865 : }
456 : : }
457 : 12 : }
458 : :
459 : : static void
460 : 39 : backing_dev_compress(struct spdk_reduce_backing_dev *backing_dev,
461 : : struct iovec *src_iov, int src_iovcnt,
462 : : struct iovec *dst_iov, int dst_iovcnt,
463 : : struct spdk_reduce_vol_cb_args *args)
464 : : {
465 : 26 : uint32_t compressed_len;
466 : 39 : uint64_t total_length = 0;
467 : 39 : char *buf = g_decomp_buf;
468 : 13 : int rc, i;
469 : :
470 : 39 : CU_ASSERT(dst_iovcnt == 1);
471 : :
472 [ + + + - ]: 126 : for (i = 0; i < src_iovcnt; i++) {
473 [ + + + + : 87 : memcpy(buf, src_iov[i].iov_base, src_iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
474 [ + - + - : 87 : buf += src_iov[i].iov_len;
+ - + - ]
475 [ + - + - : 87 : total_length += src_iov[i].iov_len;
+ - ]
476 : 29 : }
477 : :
478 [ + - + - : 39 : compressed_len = dst_iov[0].iov_len;
+ - ]
479 [ + - + - : 39 : rc = ut_compress(dst_iov[0].iov_base, &compressed_len,
+ - ]
480 : 13 : g_decomp_buf, total_length);
481 : :
482 [ + - + - ]: 39 : args->output_size = compressed_len;
483 : :
484 [ + - + - : 39 : args->cb_fn(args->cb_arg, rc);
- + + - +
- + - ]
485 : 39 : }
486 : :
487 : : static void
488 : 783 : backing_dev_decompress(struct spdk_reduce_backing_dev *backing_dev,
489 : : struct iovec *src_iov, int src_iovcnt,
490 : : struct iovec *dst_iov, int dst_iovcnt,
491 : : struct spdk_reduce_vol_cb_args *args)
492 : : {
493 : 783 : uint32_t decompressed_len = 0;
494 : 783 : char *buf = g_decomp_buf;
495 : 261 : int rc, i;
496 : :
497 : 783 : CU_ASSERT(src_iovcnt == 1);
498 : :
499 [ + + + - ]: 3060 : for (i = 0; i < dst_iovcnt; i++) {
500 [ + - + - : 2277 : decompressed_len += dst_iov[i].iov_len;
+ - ]
501 : 759 : }
502 : :
503 : 1566 : rc = ut_decompress(g_decomp_buf, &decompressed_len,
504 [ + - + - : 783 : src_iov[0].iov_base, src_iov[0].iov_len);
+ - + - +
- + - ]
505 : :
506 [ + + + - ]: 3060 : for (i = 0; i < dst_iovcnt; i++) {
507 [ + + + + : 2277 : memcpy(dst_iov[i].iov_base, buf, dst_iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
508 [ + - + - : 2277 : buf += dst_iov[i].iov_len;
+ - + - ]
509 : 759 : }
510 : :
511 [ + - + - ]: 783 : args->output_size = decompressed_len;
512 : :
513 [ + - + - : 783 : args->cb_fn(args->cb_arg, rc);
- + + - +
- + - ]
514 : 783 : }
515 : :
516 : : static void
517 : 45 : backing_dev_destroy(struct spdk_reduce_backing_dev *backing_dev)
518 : : {
519 : : /* We don't free this during backing_dev_close so that we can test init/unload/load
520 : : * scenarios.
521 : : */
522 : 45 : free(g_backing_dev_buf);
523 : 45 : free(g_decomp_buf);
524 : 45 : g_backing_dev_buf = NULL;
525 : 45 : }
526 : :
527 : : static void
528 : 48 : backing_dev_init(struct spdk_reduce_backing_dev *backing_dev, struct spdk_reduce_vol_params *params,
529 : : uint32_t backing_blocklen)
530 : : {
531 : 16 : int64_t size;
532 : :
533 : 48 : size = 4 * 1024 * 1024;
534 [ + - + - ]: 48 : backing_dev->blocklen = backing_blocklen;
535 [ + + + - : 48 : backing_dev->blockcnt = size / backing_dev->blocklen;
+ - + - +
- ]
536 [ + - + - ]: 48 : backing_dev->readv = backing_dev_readv;
537 [ + - + - ]: 48 : backing_dev->writev = backing_dev_writev;
538 [ + - + - ]: 48 : backing_dev->unmap = backing_dev_unmap;
539 [ + - + - ]: 48 : backing_dev->compress = backing_dev_compress;
540 [ + - + - ]: 48 : backing_dev->decompress = backing_dev_decompress;
541 [ + - + - ]: 48 : backing_dev->sgl_in = true;
542 [ + - + - ]: 48 : backing_dev->sgl_out = true;
543 : :
544 [ + - + - ]: 48 : g_decomp_buf = calloc(1, params->chunk_size);
545 [ + + # # ]: 48 : SPDK_CU_ASSERT_FATAL(g_decomp_buf != NULL);
546 : :
547 : 48 : g_backing_dev_buf = calloc(1, size);
548 [ + + # # ]: 48 : SPDK_CU_ASSERT_FATAL(g_backing_dev_buf != NULL);
549 : 48 : }
550 : :
551 : : static void
552 : 3 : init_md(void)
553 : : {
554 : 3 : struct spdk_reduce_vol_params params = {};
555 : 1 : struct spdk_reduce_vol_params *persistent_params;
556 : 3 : struct spdk_reduce_backing_dev backing_dev = {};
557 : 2 : struct spdk_uuid uuid;
558 : 1 : uint64_t *entry;
559 : :
560 [ + - ]: 3 : params.chunk_size = 16 * 1024;
561 [ + - ]: 3 : params.backing_io_unit_size = 512;
562 [ + - ]: 3 : params.logical_block_size = 512;
563 : :
564 : 3 : backing_dev_init(&backing_dev, ¶ms, 512);
565 : :
566 : 3 : g_vol = NULL;
567 : 3 : g_reduce_errno = -1;
568 : 3 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
569 : 3 : CU_ASSERT(g_reduce_errno == 0);
570 [ + + # # ]: 3 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
571 : : /* Confirm that reduce persisted the params to metadata. */
572 [ + + + - ]: 3 : CU_ASSERT(memcmp(g_persistent_pm_buf, SPDK_REDUCE_SIGNATURE, 8) == 0);
573 [ + - ]: 3 : persistent_params = (struct spdk_reduce_vol_params *)(g_persistent_pm_buf + 8);
574 [ + + + - ]: 3 : CU_ASSERT(memcmp(persistent_params, ¶ms, sizeof(params)) == 0);
575 : : /* Now confirm that contents of pm_file after the superblock have been initialized
576 : : * to REDUCE_EMPTY_MAP_ENTRY.
577 : : */
578 [ + - ]: 3 : entry = (uint64_t *)(g_persistent_pm_buf + sizeof(struct spdk_reduce_vol_superblock));
579 [ + + + - : 25731 : while (entry != (uint64_t *)(g_persistent_pm_buf + g_vol->pm_file.size)) {
+ - + - +
+ ]
580 [ + - ]: 25728 : CU_ASSERT(*entry == REDUCE_EMPTY_MAP_ENTRY);
581 [ + - ]: 25728 : entry++;
582 : : }
583 : :
584 : : /* Check that the pm file path was constructed correctly. It should be in
585 : : * the form:
586 : : * TEST_MD_PATH + "/" + <uuid string>
587 : : */
588 [ + - + - : 3 : CU_ASSERT(strncmp(&g_path[0], TEST_MD_PATH, strlen(TEST_MD_PATH)) == 0);
+ - + - ]
589 [ + - + - : 3 : CU_ASSERT(g_path[strlen(TEST_MD_PATH)] == '/');
+ - ]
590 [ + - + - ]: 3 : CU_ASSERT(spdk_uuid_parse(&uuid, &g_path[strlen(TEST_MD_PATH) + 1]) == 0);
591 : 3 : CU_ASSERT(spdk_uuid_compare(&uuid, spdk_reduce_vol_get_uuid(g_vol)) == 0);
592 : :
593 : 3 : g_reduce_errno = -1;
594 : 3 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
595 : 3 : CU_ASSERT(g_reduce_errno == 0);
596 : 3 : CU_ASSERT(g_volatile_pm_buf == NULL);
597 : :
598 : 3 : persistent_pm_buf_destroy();
599 : 3 : backing_dev_destroy(&backing_dev);
600 : 3 : }
601 : :
602 : : static void
603 : 6 : _init_backing_dev(uint32_t backing_blocklen)
604 : : {
605 : 6 : struct spdk_reduce_vol_params params = {};
606 : 2 : struct spdk_reduce_vol_params *persistent_params;
607 : 6 : struct spdk_reduce_backing_dev backing_dev = {};
608 : :
609 [ + - ]: 6 : params.chunk_size = 16 * 1024;
610 [ + - ]: 6 : params.backing_io_unit_size = 512;
611 [ + - ]: 6 : params.logical_block_size = 512;
612 : 6 : spdk_uuid_generate(¶ms.uuid);
613 : :
614 : 6 : backing_dev_init(&backing_dev, ¶ms, backing_blocklen);
615 : :
616 : 6 : g_vol = NULL;
617 [ + - ]: 6 : memset(g_path, 0, sizeof(g_path));
618 : 6 : g_reduce_errno = -1;
619 : 6 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
620 : 6 : CU_ASSERT(g_reduce_errno == 0);
621 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
622 [ + - + - ]: 6 : CU_ASSERT(strncmp(TEST_MD_PATH, g_path, strlen(TEST_MD_PATH)) == 0);
623 : : /* Confirm that libreduce persisted the params to the backing device. */
624 [ + + + - ]: 6 : CU_ASSERT(memcmp(g_backing_dev_buf, SPDK_REDUCE_SIGNATURE, 8) == 0);
625 [ + - ]: 6 : persistent_params = (struct spdk_reduce_vol_params *)(g_backing_dev_buf + 8);
626 [ + + + - ]: 6 : CU_ASSERT(memcmp(persistent_params, ¶ms, sizeof(params)) == 0);
627 : : /* Confirm that the path to the persistent memory metadata file was persisted to
628 : : * the backing device.
629 : : */
630 [ + + + - : 6 : CU_ASSERT(strncmp(g_path,
+ - ]
631 : : g_backing_dev_buf + REDUCE_BACKING_DEV_PATH_OFFSET,
632 : : REDUCE_PATH_MAX) == 0);
633 : :
634 : 6 : g_reduce_errno = -1;
635 : 6 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
636 : 6 : CU_ASSERT(g_reduce_errno == 0);
637 : :
638 : 6 : persistent_pm_buf_destroy();
639 : 6 : backing_dev_destroy(&backing_dev);
640 : 6 : }
641 : :
642 : : static void
643 : 3 : init_backing_dev(void)
644 : : {
645 : 3 : _init_backing_dev(512);
646 : 3 : _init_backing_dev(4096);
647 : 3 : }
648 : :
649 : : static void
650 : 6 : _load(uint32_t backing_blocklen)
651 : : {
652 : 6 : struct spdk_reduce_vol_params params = {};
653 : 6 : struct spdk_reduce_backing_dev backing_dev = {};
654 : 4 : char pmem_file_path[REDUCE_PATH_MAX];
655 : :
656 [ + - ]: 6 : params.chunk_size = 16 * 1024;
657 [ + - ]: 6 : params.backing_io_unit_size = 512;
658 [ + - ]: 6 : params.logical_block_size = 512;
659 : 6 : spdk_uuid_generate(¶ms.uuid);
660 : :
661 : 6 : backing_dev_init(&backing_dev, ¶ms, backing_blocklen);
662 : :
663 : 6 : g_vol = NULL;
664 : 6 : g_reduce_errno = -1;
665 : 6 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
666 : 6 : CU_ASSERT(g_reduce_errno == 0);
667 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
668 [ + - + - ]: 6 : CU_ASSERT(strncmp(TEST_MD_PATH, g_path, strlen(TEST_MD_PATH)) == 0);
669 [ + - + - ]: 6 : memcpy(pmem_file_path, g_path, sizeof(pmem_file_path));
670 : :
671 : 6 : g_reduce_errno = -1;
672 : 6 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
673 : 6 : CU_ASSERT(g_reduce_errno == 0);
674 : :
675 : 6 : g_vol = NULL;
676 [ + - ]: 6 : memset(g_path, 0, sizeof(g_path));
677 : 6 : g_reduce_errno = -1;
678 : 6 : spdk_reduce_vol_load(&backing_dev, load_cb, NULL);
679 : 6 : CU_ASSERT(g_reduce_errno == 0);
680 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
681 [ + - + - ]: 6 : CU_ASSERT(strncmp(g_path, pmem_file_path, sizeof(pmem_file_path)) == 0);
682 [ + - + - : 6 : CU_ASSERT(g_vol->params.vol_size == params.vol_size);
+ - + - ]
683 [ + - + - : 6 : CU_ASSERT(g_vol->params.chunk_size == params.chunk_size);
+ - + - ]
684 [ + - + - : 6 : CU_ASSERT(g_vol->params.backing_io_unit_size == params.backing_io_unit_size);
+ - + - ]
685 : :
686 : 6 : g_reduce_errno = -1;
687 : 6 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
688 : 6 : CU_ASSERT(g_reduce_errno == 0);
689 : :
690 : 6 : persistent_pm_buf_destroy();
691 : 6 : backing_dev_destroy(&backing_dev);
692 : 6 : }
693 : :
694 : : static void
695 : 3 : load(void)
696 : : {
697 : 3 : _load(512);
698 : 3 : _load(4096);
699 : 3 : }
700 : :
701 : : static uint64_t
702 : 780 : _vol_get_chunk_map_index(struct spdk_reduce_vol *vol, uint64_t offset)
703 : : {
704 [ + + + - : 780 : uint64_t logical_map_index = offset / vol->logical_blocks_per_chunk;
+ - ]
705 : :
706 [ + - + - : 780 : return vol->pm_logical_map[logical_map_index];
+ - + - ]
707 : 260 : }
708 : :
709 : : static void
710 : 45 : write_cb(void *arg, int reduce_errno)
711 : : {
712 : 45 : g_reduce_errno = reduce_errno;
713 : 45 : }
714 : :
715 : : static void
716 : 774 : read_cb(void *arg, int reduce_errno)
717 : : {
718 : 774 : g_reduce_errno = reduce_errno;
719 : 774 : }
720 : :
721 : : static void
722 : 6 : _write_maps(uint32_t backing_blocklen)
723 : 4 : {
724 : 6 : struct spdk_reduce_vol_params params = {};
725 : 6 : struct spdk_reduce_backing_dev backing_dev = {};
726 : 4 : struct iovec iov;
727 : 6 : const int bufsize = 16 * 1024; /* chunk size */
728 [ + + ]: 6 : char buf[bufsize];
729 : 2 : uint32_t num_lbas, i;
730 : 2 : uint64_t old_chunk0_map_index, new_chunk0_map_index;
731 : 2 : struct spdk_reduce_chunk_map *old_chunk0_map, *new_chunk0_map;
732 : :
733 [ + - ]: 6 : params.chunk_size = bufsize;
734 [ + - ]: 6 : params.backing_io_unit_size = 4096;
735 [ + - ]: 6 : params.logical_block_size = 512;
736 [ + + + - ]: 6 : num_lbas = bufsize / params.logical_block_size;
737 : 6 : spdk_uuid_generate(¶ms.uuid);
738 : :
739 : 6 : backing_dev_init(&backing_dev, ¶ms, backing_blocklen);
740 : :
741 : 6 : g_vol = NULL;
742 : 6 : g_reduce_errno = -1;
743 : 6 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
744 : 6 : CU_ASSERT(g_reduce_errno == 0);
745 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
746 : :
747 [ + + + + : 774 : for (i = 0; i < g_vol->params.vol_size / g_vol->params.chunk_size; i++) {
+ - + - +
- + - + -
+ + ]
748 : 768 : CU_ASSERT(_vol_get_chunk_map_index(g_vol, i) == REDUCE_EMPTY_MAP_ENTRY);
749 : 256 : }
750 : :
751 : 6 : ut_build_data_buffer(buf, bufsize, 0x00, 1);
752 : 6 : iov.iov_base = buf;
753 [ + - ]: 6 : iov.iov_len = bufsize;
754 : 6 : g_reduce_errno = -1;
755 : 6 : spdk_reduce_vol_writev(g_vol, &iov, 1, 0, num_lbas, write_cb, NULL);
756 : 6 : CU_ASSERT(g_reduce_errno == 0);
757 : :
758 : 6 : old_chunk0_map_index = _vol_get_chunk_map_index(g_vol, 0);
759 : 6 : CU_ASSERT(old_chunk0_map_index != REDUCE_EMPTY_MAP_ENTRY);
760 [ + - + - ]: 6 : CU_ASSERT(spdk_bit_array_get(g_vol->allocated_chunk_maps, old_chunk0_map_index) == true);
761 : :
762 : 6 : old_chunk0_map = _reduce_vol_get_chunk_map(g_vol, old_chunk0_map_index);
763 [ + + + - : 30 : for (i = 0; i < g_vol->backing_io_units_per_chunk; i++) {
+ + ]
764 [ + - + - : 24 : CU_ASSERT(old_chunk0_map->io_unit_index[i] != REDUCE_EMPTY_MAP_ENTRY);
+ - ]
765 [ + - + - : 24 : CU_ASSERT(spdk_bit_array_get(g_vol->allocated_backing_io_units,
+ - + - +
- ]
766 : : old_chunk0_map->io_unit_index[i]) == true);
767 : 8 : }
768 : :
769 : 6 : g_reduce_errno = -1;
770 : 6 : spdk_reduce_vol_writev(g_vol, &iov, 1, 0, num_lbas, write_cb, NULL);
771 : 6 : CU_ASSERT(g_reduce_errno == 0);
772 : :
773 : 6 : new_chunk0_map_index = _vol_get_chunk_map_index(g_vol, 0);
774 : 6 : CU_ASSERT(new_chunk0_map_index != REDUCE_EMPTY_MAP_ENTRY);
775 : 6 : CU_ASSERT(new_chunk0_map_index != old_chunk0_map_index);
776 [ + - + - ]: 6 : CU_ASSERT(spdk_bit_array_get(g_vol->allocated_chunk_maps, new_chunk0_map_index) == true);
777 [ + - + - ]: 6 : CU_ASSERT(spdk_bit_array_get(g_vol->allocated_chunk_maps, old_chunk0_map_index) == false);
778 : :
779 [ + + + - : 30 : for (i = 0; i < g_vol->backing_io_units_per_chunk; i++) {
+ + ]
780 [ + - + - : 24 : CU_ASSERT(spdk_bit_array_get(g_vol->allocated_backing_io_units,
+ - + - +
- ]
781 : : old_chunk0_map->io_unit_index[i]) == false);
782 : 8 : }
783 : :
784 : 6 : new_chunk0_map = _reduce_vol_get_chunk_map(g_vol, new_chunk0_map_index);
785 [ + + + - : 30 : for (i = 0; i < g_vol->backing_io_units_per_chunk; i++) {
+ + ]
786 [ + - + - : 24 : CU_ASSERT(new_chunk0_map->io_unit_index[i] != REDUCE_EMPTY_MAP_ENTRY);
+ - ]
787 [ + - + - : 24 : CU_ASSERT(spdk_bit_array_get(g_vol->allocated_backing_io_units,
+ - + - +
- ]
788 : : new_chunk0_map->io_unit_index[i]) == true);
789 : 8 : }
790 : :
791 : 6 : g_reduce_errno = -1;
792 : 6 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
793 : 6 : CU_ASSERT(g_reduce_errno == 0);
794 : :
795 : 6 : g_vol = NULL;
796 : 6 : g_reduce_errno = -1;
797 : 6 : spdk_reduce_vol_load(&backing_dev, load_cb, NULL);
798 : 6 : CU_ASSERT(g_reduce_errno == 0);
799 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
800 [ + - + - : 6 : CU_ASSERT(g_vol->params.vol_size == params.vol_size);
+ - + - ]
801 [ + - + - : 6 : CU_ASSERT(g_vol->params.chunk_size == params.chunk_size);
+ - + - ]
802 [ + - + - : 6 : CU_ASSERT(g_vol->params.backing_io_unit_size == params.backing_io_unit_size);
+ - + - ]
803 : :
804 : 6 : g_reduce_errno = -1;
805 : 6 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
806 : 6 : CU_ASSERT(g_reduce_errno == 0);
807 : :
808 : 6 : persistent_pm_buf_destroy();
809 : 6 : backing_dev_destroy(&backing_dev);
810 : 6 : }
811 : :
812 : : static void
813 : 3 : write_maps(void)
814 : : {
815 : 3 : _write_maps(512);
816 : 3 : _write_maps(4096);
817 : 3 : }
818 : :
819 : : static void
820 : 6 : _read_write(uint32_t backing_blocklen)
821 : : {
822 : 6 : struct spdk_reduce_vol_params params = {};
823 : 6 : struct spdk_reduce_backing_dev backing_dev = {};
824 : 4 : struct iovec iov;
825 : 4 : char buf[16 * 1024]; /* chunk size */
826 : 4 : char compare_buf[16 * 1024];
827 : 2 : uint32_t i;
828 : :
829 [ + - ]: 6 : params.chunk_size = 16 * 1024;
830 [ + - ]: 6 : params.backing_io_unit_size = 4096;
831 [ + - ]: 6 : params.logical_block_size = 512;
832 : 6 : spdk_uuid_generate(¶ms.uuid);
833 : :
834 : 6 : backing_dev_init(&backing_dev, ¶ms, backing_blocklen);
835 : :
836 : 6 : g_vol = NULL;
837 : 6 : g_reduce_errno = -1;
838 : 6 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
839 : 6 : CU_ASSERT(g_reduce_errno == 0);
840 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
841 : :
842 : : /* Write 0xAA to 2 512-byte logical blocks, starting at LBA 2. */
843 [ + - + - ]: 6 : memset(buf, 0xAA, 2 * params.logical_block_size);
844 : 6 : iov.iov_base = buf;
845 [ + - + - ]: 6 : iov.iov_len = 2 * params.logical_block_size;
846 : 6 : g_reduce_errno = -1;
847 : 6 : spdk_reduce_vol_writev(g_vol, &iov, 1, 2, 2, write_cb, NULL);
848 : 6 : CU_ASSERT(g_reduce_errno == 0);
849 : :
850 [ + - ]: 6 : memset(compare_buf, 0xAA, sizeof(compare_buf));
851 [ + + + + : 198 : for (i = 0; i < params.chunk_size / params.logical_block_size; i++) {
+ - + + ]
852 [ + - + - ]: 192 : memset(buf, 0xFF, params.logical_block_size);
853 : 192 : iov.iov_base = buf;
854 [ + - + - ]: 192 : iov.iov_len = params.logical_block_size;
855 : 192 : g_reduce_errno = -1;
856 : 192 : spdk_reduce_vol_readv(g_vol, &iov, 1, i, 1, read_cb, NULL);
857 : 192 : CU_ASSERT(g_reduce_errno == 0);
858 : :
859 [ + + ]: 192 : switch (i) {
860 : 8 : case 2:
861 : : case 3:
862 [ + - + - : 12 : CU_ASSERT(memcmp(buf, compare_buf, params.logical_block_size) == 0);
+ - ]
863 : 12 : break;
864 : 120 : default:
865 [ + - ]: 180 : CU_ASSERT(spdk_mem_all_zero(buf, params.logical_block_size));
866 : 180 : break;
867 : : }
868 : 64 : }
869 : :
870 : 6 : g_reduce_errno = -1;
871 : 6 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
872 : 6 : CU_ASSERT(g_reduce_errno == 0);
873 : :
874 : : /* Overwrite what we just wrote with 0xCC */
875 : 6 : g_vol = NULL;
876 : 6 : g_reduce_errno = -1;
877 : 6 : spdk_reduce_vol_load(&backing_dev, load_cb, NULL);
878 : 6 : CU_ASSERT(g_reduce_errno == 0);
879 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
880 [ + - + - : 6 : CU_ASSERT(g_vol->params.vol_size == params.vol_size);
+ - + - ]
881 [ + - + - : 6 : CU_ASSERT(g_vol->params.chunk_size == params.chunk_size);
+ - + - ]
882 [ + - + - : 6 : CU_ASSERT(g_vol->params.backing_io_unit_size == params.backing_io_unit_size);
+ - + - ]
883 : :
884 [ + - + - ]: 6 : memset(buf, 0xCC, 2 * params.logical_block_size);
885 : 6 : iov.iov_base = buf;
886 [ + - + - ]: 6 : iov.iov_len = 2 * params.logical_block_size;
887 : 6 : g_reduce_errno = -1;
888 : 6 : spdk_reduce_vol_writev(g_vol, &iov, 1, 2, 2, write_cb, NULL);
889 : 6 : CU_ASSERT(g_reduce_errno == 0);
890 : :
891 [ + - ]: 6 : memset(compare_buf, 0xCC, sizeof(compare_buf));
892 [ + + + + : 198 : for (i = 0; i < params.chunk_size / params.logical_block_size; i++) {
+ - + + ]
893 [ + - + - ]: 192 : memset(buf, 0xFF, params.logical_block_size);
894 : 192 : iov.iov_base = buf;
895 [ + - + - ]: 192 : iov.iov_len = params.logical_block_size;
896 : 192 : g_reduce_errno = -1;
897 : 192 : spdk_reduce_vol_readv(g_vol, &iov, 1, i, 1, read_cb, NULL);
898 : 192 : CU_ASSERT(g_reduce_errno == 0);
899 : :
900 [ + + ]: 192 : switch (i) {
901 : 8 : case 2:
902 : : case 3:
903 [ + - + - : 12 : CU_ASSERT(memcmp(buf, compare_buf, params.logical_block_size) == 0);
+ - ]
904 : 12 : break;
905 : 120 : default:
906 [ + - ]: 180 : CU_ASSERT(spdk_mem_all_zero(buf, params.logical_block_size));
907 : 180 : break;
908 : : }
909 : 64 : }
910 : :
911 : 6 : g_reduce_errno = -1;
912 : 6 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
913 : 6 : CU_ASSERT(g_reduce_errno == 0);
914 : :
915 : 6 : g_vol = NULL;
916 : 6 : g_reduce_errno = -1;
917 : 6 : spdk_reduce_vol_load(&backing_dev, load_cb, NULL);
918 : 6 : CU_ASSERT(g_reduce_errno == 0);
919 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
920 [ + - + - : 6 : CU_ASSERT(g_vol->params.vol_size == params.vol_size);
+ - + - ]
921 [ + - + - : 6 : CU_ASSERT(g_vol->params.chunk_size == params.chunk_size);
+ - + - ]
922 [ + - + - : 6 : CU_ASSERT(g_vol->params.backing_io_unit_size == params.backing_io_unit_size);
+ - + - ]
923 : :
924 : 6 : g_reduce_errno = -1;
925 : :
926 : : /* Write 0xBB to 2 512-byte logical blocks, starting at LBA 37.
927 : : * This is writing into the second chunk of the volume. This also
928 : : * enables implicitly checking that we reloaded the bit arrays
929 : : * correctly - making sure we don't use the first chunk map again
930 : : * for this new write - the first chunk map was already used by the
931 : : * write from before we unloaded and reloaded.
932 : : */
933 [ + - + - ]: 6 : memset(buf, 0xBB, 2 * params.logical_block_size);
934 : 6 : iov.iov_base = buf;
935 [ + - + - ]: 6 : iov.iov_len = 2 * params.logical_block_size;
936 : 6 : g_reduce_errno = -1;
937 : 6 : spdk_reduce_vol_writev(g_vol, &iov, 1, 37, 2, write_cb, NULL);
938 : 6 : CU_ASSERT(g_reduce_errno == 0);
939 : :
940 [ + + + + : 390 : for (i = 0; i < 2 * params.chunk_size / params.logical_block_size; i++) {
+ - + + ]
941 [ + - + - ]: 384 : memset(buf, 0xFF, params.logical_block_size);
942 : 384 : iov.iov_base = buf;
943 [ + - + - ]: 384 : iov.iov_len = params.logical_block_size;
944 : 384 : g_reduce_errno = -1;
945 : 384 : spdk_reduce_vol_readv(g_vol, &iov, 1, i, 1, read_cb, NULL);
946 : 384 : CU_ASSERT(g_reduce_errno == 0);
947 : :
948 [ + + + ]: 384 : switch (i) {
949 : 8 : case 2:
950 : : case 3:
951 [ + - ]: 12 : memset(compare_buf, 0xCC, sizeof(compare_buf));
952 [ + - + - : 12 : CU_ASSERT(memcmp(buf, compare_buf, params.logical_block_size) == 0);
+ - ]
953 : 12 : break;
954 : 8 : case 37:
955 : : case 38:
956 [ + - ]: 12 : memset(compare_buf, 0xBB, sizeof(compare_buf));
957 [ + - + - : 12 : CU_ASSERT(memcmp(buf, compare_buf, params.logical_block_size) == 0);
+ - ]
958 : 12 : break;
959 : 240 : default:
960 [ + - ]: 360 : CU_ASSERT(spdk_mem_all_zero(buf, params.logical_block_size));
961 : 360 : break;
962 : : }
963 : 128 : }
964 : :
965 : 6 : g_reduce_errno = -1;
966 : 6 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
967 : 6 : CU_ASSERT(g_reduce_errno == 0);
968 : :
969 : 6 : persistent_pm_buf_destroy();
970 : 6 : backing_dev_destroy(&backing_dev);
971 : 6 : }
972 : :
973 : : static void
974 : 3 : read_write(void)
975 : : {
976 : 3 : _read_write(512);
977 : 3 : _read_write(4096);
978 : 3 : }
979 : :
980 : : static void
981 : 6 : _readv_writev(uint32_t backing_blocklen)
982 : : {
983 : 6 : struct spdk_reduce_vol_params params = {};
984 : 6 : struct spdk_reduce_backing_dev backing_dev = {};
985 : 4 : struct iovec iov[REDUCE_MAX_IOVECS + 1];
986 : :
987 [ + - ]: 6 : params.chunk_size = 16 * 1024;
988 [ + - ]: 6 : params.backing_io_unit_size = 4096;
989 [ + - ]: 6 : params.logical_block_size = 512;
990 : 6 : spdk_uuid_generate(¶ms.uuid);
991 : :
992 : 6 : backing_dev_init(&backing_dev, ¶ms, backing_blocklen);
993 : :
994 : 6 : g_vol = NULL;
995 : 6 : g_reduce_errno = -1;
996 : 6 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
997 : 6 : CU_ASSERT(g_reduce_errno == 0);
998 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
999 : :
1000 : 6 : g_reduce_errno = -1;
1001 : 6 : spdk_reduce_vol_writev(g_vol, iov, REDUCE_MAX_IOVECS + 1, 2, REDUCE_MAX_IOVECS + 1, write_cb, NULL);
1002 : 6 : CU_ASSERT(g_reduce_errno == -EINVAL);
1003 : :
1004 : 6 : g_reduce_errno = -1;
1005 : 6 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
1006 : 6 : CU_ASSERT(g_reduce_errno == 0);
1007 : :
1008 : 6 : persistent_pm_buf_destroy();
1009 : 6 : backing_dev_destroy(&backing_dev);
1010 : 6 : }
1011 : :
1012 : : static void
1013 : 3 : readv_writev(void)
1014 : : {
1015 : 3 : _readv_writev(512);
1016 : 3 : _readv_writev(4096);
1017 : 3 : }
1018 : :
1019 : : static void
1020 : 3 : destroy_cb(void *ctx, int reduce_errno)
1021 : : {
1022 : 3 : g_reduce_errno = reduce_errno;
1023 : 3 : }
1024 : :
1025 : : static void
1026 : 3 : destroy(void)
1027 : : {
1028 : 3 : struct spdk_reduce_vol_params params = {};
1029 : 3 : struct spdk_reduce_backing_dev backing_dev = {};
1030 : :
1031 [ + - ]: 3 : params.chunk_size = 16 * 1024;
1032 [ + - ]: 3 : params.backing_io_unit_size = 512;
1033 [ + - ]: 3 : params.logical_block_size = 512;
1034 : 3 : spdk_uuid_generate(¶ms.uuid);
1035 : :
1036 : 3 : backing_dev_init(&backing_dev, ¶ms, 512);
1037 : :
1038 : 3 : g_vol = NULL;
1039 : 3 : g_reduce_errno = -1;
1040 : 3 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
1041 : 3 : CU_ASSERT(g_reduce_errno == 0);
1042 [ + + # # ]: 3 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
1043 : :
1044 : 3 : g_reduce_errno = -1;
1045 : 3 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
1046 : 3 : CU_ASSERT(g_reduce_errno == 0);
1047 : :
1048 : 3 : g_vol = NULL;
1049 : 3 : g_reduce_errno = -1;
1050 : 3 : spdk_reduce_vol_load(&backing_dev, load_cb, NULL);
1051 : 3 : CU_ASSERT(g_reduce_errno == 0);
1052 [ + + # # ]: 3 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
1053 : :
1054 : 3 : g_reduce_errno = -1;
1055 : 3 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
1056 : 3 : CU_ASSERT(g_reduce_errno == 0);
1057 : :
1058 : 3 : g_reduce_errno = -1;
1059 : 3 : MOCK_CLEAR(spdk_malloc);
1060 : 3 : MOCK_CLEAR(spdk_zmalloc);
1061 : 3 : spdk_reduce_vol_destroy(&backing_dev, destroy_cb, NULL);
1062 : 3 : CU_ASSERT(g_reduce_errno == 0);
1063 : :
1064 : 3 : g_reduce_errno = 0;
1065 : 3 : spdk_reduce_vol_load(&backing_dev, load_cb, NULL);
1066 : 3 : CU_ASSERT(g_reduce_errno == -EILSEQ);
1067 : :
1068 : 3 : backing_dev_destroy(&backing_dev);
1069 : 3 : }
1070 : :
1071 : : /* This test primarily checks that the reduce unit test infrastructure for asynchronous
1072 : : * backing device I/O operations is working correctly.
1073 : : */
1074 : : static void
1075 : 3 : defer_bdev_io(void)
1076 : 2 : {
1077 : 3 : struct spdk_reduce_vol_params params = {};
1078 : 3 : struct spdk_reduce_backing_dev backing_dev = {};
1079 : 3 : const uint32_t logical_block_size = 512;
1080 : 2 : struct iovec iov;
1081 [ + + ]: 3 : char buf[logical_block_size];
1082 [ + + ]: 3 : char compare_buf[logical_block_size];
1083 : :
1084 [ + - ]: 3 : params.chunk_size = 16 * 1024;
1085 [ + - ]: 3 : params.backing_io_unit_size = 4096;
1086 [ + - ]: 3 : params.logical_block_size = logical_block_size;
1087 : 3 : spdk_uuid_generate(¶ms.uuid);
1088 : :
1089 : 3 : backing_dev_init(&backing_dev, ¶ms, 512);
1090 : :
1091 : 3 : g_vol = NULL;
1092 : 3 : g_reduce_errno = -1;
1093 : 3 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
1094 : 3 : CU_ASSERT(g_reduce_errno == 0);
1095 [ + + # # ]: 3 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
1096 : :
1097 : : /* Write 0xAA to 1 512-byte logical block. */
1098 [ + + + - ]: 3 : memset(buf, 0xAA, params.logical_block_size);
1099 : 3 : iov.iov_base = buf;
1100 [ + - + - ]: 3 : iov.iov_len = params.logical_block_size;
1101 : 3 : g_reduce_errno = -100;
1102 : 3 : g_defer_bdev_io = true;
1103 : 3 : spdk_reduce_vol_writev(g_vol, &iov, 1, 0, 1, write_cb, NULL);
1104 : : /* Callback should not have executed, so this should still equal -100. */
1105 : 3 : CU_ASSERT(g_reduce_errno == -100);
1106 : 3 : CU_ASSERT(!TAILQ_EMPTY(&g_pending_bdev_io));
1107 : : /* We wrote to just 512 bytes of one chunk which was previously unallocated. This
1108 : : * should result in 1 pending I/O since the rest of this chunk will be zeroes and
1109 : : * very compressible.
1110 : : */
1111 : 3 : CU_ASSERT(g_pending_bdev_io_count == 1);
1112 : :
1113 : 3 : backing_dev_io_execute(0);
1114 : 3 : CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io));
1115 : 3 : CU_ASSERT(g_reduce_errno == 0);
1116 : :
1117 : 3 : g_defer_bdev_io = false;
1118 [ + + ]: 3 : memset(compare_buf, 0xAA, sizeof(compare_buf));
1119 [ + + ]: 3 : memset(buf, 0xFF, sizeof(buf));
1120 : 3 : iov.iov_base = buf;
1121 [ + - + - ]: 3 : iov.iov_len = params.logical_block_size;
1122 : 3 : g_reduce_errno = -100;
1123 : 3 : spdk_reduce_vol_readv(g_vol, &iov, 1, 0, 1, read_cb, NULL);
1124 : 3 : CU_ASSERT(g_reduce_errno == 0);
1125 [ + + + + ]: 3 : CU_ASSERT(memcmp(buf, compare_buf, sizeof(buf)) == 0);
1126 : :
1127 : 3 : g_reduce_errno = -1;
1128 : 3 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
1129 : 3 : CU_ASSERT(g_reduce_errno == 0);
1130 : :
1131 : 3 : persistent_pm_buf_destroy();
1132 : 3 : backing_dev_destroy(&backing_dev);
1133 : 3 : }
1134 : :
1135 : : static void
1136 : 3 : overlapped(void)
1137 : 2 : {
1138 : 3 : struct spdk_reduce_vol_params params = {};
1139 : 3 : struct spdk_reduce_backing_dev backing_dev = {};
1140 : 3 : const uint32_t logical_block_size = 512;
1141 : 2 : struct iovec iov;
1142 [ + + ]: 3 : char buf[2 * logical_block_size];
1143 [ + + ]: 3 : char compare_buf[2 * logical_block_size];
1144 : :
1145 [ + - ]: 3 : params.chunk_size = 16 * 1024;
1146 [ + - ]: 3 : params.backing_io_unit_size = 4096;
1147 [ + - ]: 3 : params.logical_block_size = logical_block_size;
1148 : 3 : spdk_uuid_generate(¶ms.uuid);
1149 : :
1150 : 3 : backing_dev_init(&backing_dev, ¶ms, 512);
1151 : :
1152 : 3 : g_vol = NULL;
1153 : 3 : g_reduce_errno = -1;
1154 : 3 : spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
1155 : 3 : CU_ASSERT(g_reduce_errno == 0);
1156 [ + + # # ]: 3 : SPDK_CU_ASSERT_FATAL(g_vol != NULL);
1157 : :
1158 : : /* Write 0xAA to 1 512-byte logical block. */
1159 [ + + ]: 3 : memset(buf, 0xAA, logical_block_size);
1160 : 3 : iov.iov_base = buf;
1161 [ + - ]: 3 : iov.iov_len = logical_block_size;
1162 : 3 : g_reduce_errno = -100;
1163 : 3 : g_defer_bdev_io = true;
1164 : 3 : spdk_reduce_vol_writev(g_vol, &iov, 1, 0, 1, write_cb, NULL);
1165 : : /* Callback should not have executed, so this should still equal -100. */
1166 : 3 : CU_ASSERT(g_reduce_errno == -100);
1167 : 3 : CU_ASSERT(!TAILQ_EMPTY(&g_pending_bdev_io));
1168 : : /* We wrote to just 512 bytes of one chunk which was previously unallocated. This
1169 : : * should result in 1 pending I/O since the rest of this chunk will be zeroes and
1170 : : * very compressible.
1171 : : */
1172 : 3 : CU_ASSERT(g_pending_bdev_io_count == 1);
1173 : :
1174 : : /* Now do an overlapped I/O to the same chunk. */
1175 : 3 : spdk_reduce_vol_writev(g_vol, &iov, 1, 1, 1, write_cb, NULL);
1176 : : /* Callback should not have executed, so this should still equal -100. */
1177 : 3 : CU_ASSERT(g_reduce_errno == -100);
1178 : 3 : CU_ASSERT(!TAILQ_EMPTY(&g_pending_bdev_io));
1179 : : /* The second I/O overlaps with the first one. So we should only see pending bdev_io
1180 : : * related to the first I/O here - the second one won't start until the first one is completed.
1181 : : */
1182 : 3 : CU_ASSERT(g_pending_bdev_io_count == 1);
1183 : :
1184 : 3 : backing_dev_io_execute(0);
1185 : 3 : CU_ASSERT(g_reduce_errno == 0);
1186 : :
1187 : 3 : g_defer_bdev_io = false;
1188 [ + + ]: 3 : memset(compare_buf, 0xAA, sizeof(compare_buf));
1189 [ + + ]: 3 : memset(buf, 0xFF, sizeof(buf));
1190 : 3 : iov.iov_base = buf;
1191 [ + - ]: 3 : iov.iov_len = 2 * logical_block_size;
1192 : 3 : g_reduce_errno = -100;
1193 : 3 : spdk_reduce_vol_readv(g_vol, &iov, 1, 0, 2, read_cb, NULL);
1194 : 3 : CU_ASSERT(g_reduce_errno == 0);
1195 [ + + + + ]: 3 : CU_ASSERT(memcmp(buf, compare_buf, 2 * logical_block_size) == 0);
1196 : :
1197 : 3 : g_reduce_errno = -1;
1198 : 3 : spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
1199 : 3 : CU_ASSERT(g_reduce_errno == 0);
1200 : :
1201 : 3 : persistent_pm_buf_destroy();
1202 : 3 : backing_dev_destroy(&backing_dev);
1203 : 3 : }
1204 : :
1205 : : #define BUFSIZE 4096
1206 : :
1207 : : static void
1208 : 3 : compress_algorithm(void)
1209 : : {
1210 : 2 : uint8_t original_data[BUFSIZE];
1211 : 2 : uint8_t compressed_data[BUFSIZE];
1212 : 2 : uint8_t decompressed_data[BUFSIZE];
1213 : 2 : uint32_t compressed_len, decompressed_len;
1214 : 1 : int rc;
1215 : :
1216 : 3 : ut_build_data_buffer(original_data, BUFSIZE, 0xAA, BUFSIZE);
1217 : 3 : compressed_len = sizeof(compressed_data);
1218 : 3 : rc = ut_compress(compressed_data, &compressed_len, original_data, UINT8_MAX);
1219 : 3 : CU_ASSERT(rc == 0);
1220 : 3 : CU_ASSERT(compressed_len == 2);
1221 [ + - + - ]: 3 : CU_ASSERT(compressed_data[0] == UINT8_MAX);
1222 [ + - + - : 3 : CU_ASSERT(compressed_data[1] == 0xAA);
+ - ]
1223 : :
1224 : 3 : decompressed_len = sizeof(decompressed_data);
1225 : 3 : rc = ut_decompress(decompressed_data, &decompressed_len, compressed_data, compressed_len);
1226 : 3 : CU_ASSERT(rc == 0);
1227 : 3 : CU_ASSERT(decompressed_len == UINT8_MAX);
1228 [ + - + - ]: 3 : CU_ASSERT(memcmp(original_data, decompressed_data, decompressed_len) == 0);
1229 : :
1230 : 3 : compressed_len = sizeof(compressed_data);
1231 : 3 : rc = ut_compress(compressed_data, &compressed_len, original_data, UINT8_MAX + 1);
1232 : 3 : CU_ASSERT(rc == 0);
1233 : 3 : CU_ASSERT(compressed_len == 4);
1234 [ + - + - ]: 3 : CU_ASSERT(compressed_data[0] == UINT8_MAX);
1235 [ + - + - : 3 : CU_ASSERT(compressed_data[1] == 0xAA);
+ - ]
1236 [ + - + - : 3 : CU_ASSERT(compressed_data[2] == 1);
+ - ]
1237 [ + - + - : 3 : CU_ASSERT(compressed_data[3] == 0xAA);
+ - ]
1238 : :
1239 : 3 : decompressed_len = sizeof(decompressed_data);
1240 : 3 : rc = ut_decompress(decompressed_data, &decompressed_len, compressed_data, compressed_len);
1241 : 3 : CU_ASSERT(rc == 0);
1242 : 3 : CU_ASSERT(decompressed_len == UINT8_MAX + 1);
1243 [ + - + - ]: 3 : CU_ASSERT(memcmp(original_data, decompressed_data, decompressed_len) == 0);
1244 : :
1245 : 3 : ut_build_data_buffer(original_data, BUFSIZE, 0x00, 1);
1246 : 3 : compressed_len = sizeof(compressed_data);
1247 : 3 : rc = ut_compress(compressed_data, &compressed_len, original_data, 2048);
1248 : 3 : CU_ASSERT(rc == 0);
1249 : 3 : CU_ASSERT(compressed_len == 4096);
1250 [ + - + - ]: 3 : CU_ASSERT(compressed_data[0] == 1);
1251 [ + - + - : 3 : CU_ASSERT(compressed_data[1] == 0);
+ - ]
1252 [ + - + - : 3 : CU_ASSERT(compressed_data[4094] == 1);
+ - ]
1253 [ + - + - : 3 : CU_ASSERT(compressed_data[4095] == 0xFF);
+ - ]
1254 : :
1255 : 3 : decompressed_len = sizeof(decompressed_data);
1256 : 3 : rc = ut_decompress(decompressed_data, &decompressed_len, compressed_data, compressed_len);
1257 : 3 : CU_ASSERT(rc == 0);
1258 : 3 : CU_ASSERT(decompressed_len == 2048);
1259 [ + - + - ]: 3 : CU_ASSERT(memcmp(original_data, decompressed_data, decompressed_len) == 0);
1260 : :
1261 : 3 : compressed_len = sizeof(compressed_data);
1262 : 3 : rc = ut_compress(compressed_data, &compressed_len, original_data, 2049);
1263 : 3 : CU_ASSERT(rc == -ENOSPC);
1264 : 3 : }
1265 : :
1266 : : static void
1267 : 3 : test_prepare_compress_chunk(void)
1268 : : {
1269 : 3 : struct spdk_reduce_vol vol = {};
1270 : 3 : struct spdk_reduce_backing_dev backing_dev = {};
1271 : 3 : struct spdk_reduce_vol_request req = {};
1272 : 2 : void *buf;
1273 : 1 : char *buffer_end, *aligned_user_buffer, *unaligned_user_buffer;
1274 : 3 : char decomp_buffer[16 * 1024] = {};
1275 : 3 : char comp_buffer[16 * 1024] = {};
1276 : 3 : struct iovec user_iov[2] = {};
1277 : 3 : size_t user_buffer_iov_len = 8192;
1278 : 1 : size_t remainder_bytes;
1279 : 1 : size_t offset_bytes;
1280 : 1 : size_t memcmp_offset;
1281 : 1 : uint32_t i;
1282 : :
1283 [ + - ]: 3 : vol.params.chunk_size = 16 * 1024;
1284 [ + - ]: 3 : vol.params.backing_io_unit_size = 4096;
1285 [ + - ]: 3 : vol.params.logical_block_size = 512;
1286 : 3 : backing_dev_init(&backing_dev, &vol.params, 512);
1287 [ + - ]: 3 : vol.backing_dev = &backing_dev;
1288 [ + + + - : 3 : vol.logical_blocks_per_chunk = vol.params.chunk_size / vol.params.logical_block_size;
+ - + - ]
1289 : :
1290 : : /* Allocate 1 extra byte to test a case when buffer crosses huge page boundary */
1291 [ + + + - : 3 : SPDK_CU_ASSERT_FATAL(posix_memalign(&buf, VALUE_2MB, VALUE_2MB + 1) == 0);
+ - + - #
# ]
1292 [ + - + - : 3 : buffer_end = (char *)buf + VALUE_2MB + 1;
+ - ]
1293 : 3 : aligned_user_buffer = (char *)buf;
1294 [ + + + - ]: 3 : memset(aligned_user_buffer, 0xc, vol.params.chunk_size);
1295 [ + - + - ]: 3 : unaligned_user_buffer = buffer_end - vol.params.chunk_size;
1296 [ + + + - ]: 3 : memset(unaligned_user_buffer, 0xc, vol.params.chunk_size);
1297 : :
1298 [ + - ]: 3 : req.vol = &vol;
1299 : 3 : req.decomp_buf = decomp_buffer;
1300 [ + - ]: 3 : req.comp_buf = comp_buffer;
1301 [ + - ]: 3 : req.iov = user_iov;
1302 [ + - ]: 3 : req.iovcnt = 2;
1303 [ + - ]: 3 : req.offset = 0;
1304 : :
1305 : : /* Part 1 - backing dev supports sgl_in */
1306 : : /* Test 1 - user's buffers length equals to chunk_size */
1307 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1308 [ + - + - : 6 : req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len;
+ - + - +
- ]
1309 [ + - + - : 6 : req.iov[i].iov_len = user_buffer_iov_len;
+ - + - ]
1310 : 2 : }
1311 : :
1312 : 3 : _prepare_compress_chunk(&req, false);
1313 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 2);
1314 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1315 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base);
+ - + - +
- + - + -
+ - ]
1316 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
1317 : 2 : }
1318 : :
1319 : 3 : _prepare_compress_chunk(&req, true);
1320 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 2);
1321 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1322 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base);
+ - + - +
- + - + -
+ - ]
1323 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
1324 : 2 : }
1325 : :
1326 : : /* Test 2 - user's buffer less than chunk_size, without offset */
1327 : 3 : user_buffer_iov_len = 4096;
1328 [ + - ]: 3 : remainder_bytes = vol.params.chunk_size - user_buffer_iov_len * 2;
1329 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1330 [ + - + - : 6 : req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len;
+ - + - +
- ]
1331 [ + - + - : 6 : req.iov[i].iov_len = user_buffer_iov_len;
+ - + - ]
1332 : 2 : }
1333 : :
1334 : 3 : _prepare_compress_chunk(&req, false);
1335 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 3);
1336 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1337 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base);
+ - + - +
- + - + -
+ - ]
1338 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
1339 : 2 : }
1340 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[i].iov_base == req.decomp_buf + user_buffer_iov_len * 2);
+ - + - +
- ]
1341 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[i].iov_len == remainder_bytes);
+ - + - ]
1342 : :
1343 : 3 : _prepare_compress_chunk(&req, true);
1344 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 3);
1345 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1346 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base);
+ - + - +
- + - + -
+ - ]
1347 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
1348 : 2 : }
1349 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[i].iov_base == g_zero_buf + user_buffer_iov_len * 2);
+ - + - +
- ]
1350 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[i].iov_len == remainder_bytes);
+ - + - ]
1351 : :
1352 : : /* Test 3 - user's buffer less than chunk_size, non zero offset */
1353 : 3 : user_buffer_iov_len = 4096;
1354 [ + - ]: 3 : req.offset = 3;
1355 [ + - + - ]: 3 : offset_bytes = req.offset * vol.params.logical_block_size;
1356 [ + - ]: 3 : remainder_bytes = vol.params.chunk_size - offset_bytes - user_buffer_iov_len * 2;
1357 : :
1358 : 3 : _prepare_compress_chunk(&req, false);
1359 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 4);
1360 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1361 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == offset_bytes);
+ - + - ]
1362 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1363 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i + 1].iov_base == req.iov[i].iov_base);
+ - + - +
- + - + -
+ - ]
1364 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i + 1].iov_len == req.iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
1365 : 2 : }
1366 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[3].iov_base == req.decomp_buf + offset_bytes + user_buffer_iov_len * 2);
+ - + - +
- + - ]
1367 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[3].iov_len == remainder_bytes);
+ - + - ]
1368 : :
1369 : 3 : _prepare_compress_chunk(&req, true);
1370 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 4);
1371 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == g_zero_buf);
+ - + - ]
1372 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == offset_bytes);
+ - + - ]
1373 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1374 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i + 1].iov_base == req.iov[i].iov_base);
+ - + - +
- + - + -
+ - ]
1375 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i + 1].iov_len == req.iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
1376 : 2 : }
1377 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[3].iov_base == g_zero_buf + offset_bytes + user_buffer_iov_len * 2);
+ - + - +
- + - ]
1378 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[3].iov_len == remainder_bytes);
+ - + - ]
1379 : :
1380 : : /* Part 2 - backing dev doesn't support sgl_in */
1381 : : /* Test 1 - user's buffers length equals to chunk_size
1382 : : * user's buffers are copied */
1383 [ + - + - : 3 : vol.backing_dev->sgl_in = false;
+ - ]
1384 [ + - ]: 3 : req.offset = 0;
1385 : 3 : user_buffer_iov_len = 8192;
1386 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1387 [ + - + - : 6 : req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len;
+ - + - +
- ]
1388 [ + - + - : 6 : req.iov[i].iov_len = user_buffer_iov_len;
+ - + - ]
1389 [ + + + - : 6 : memset(req.iov[i].iov_base, 0xb + i, req.iov[i].iov_len);
+ - + - +
- + - + -
+ - + - ]
1390 : 2 : }
1391 : :
1392 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1393 : :
1394 : 3 : _prepare_compress_chunk(&req, false);
1395 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1396 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1397 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1398 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base, req.iov[0].iov_base, req.iov[0].iov_len) == 0);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1399 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + req.iov[0].iov_len, req.iov[1].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
1400 : : req.iov[1].iov_len) == 0);
1401 : :
1402 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1403 : :
1404 : 3 : _prepare_compress_chunk(&req, true);
1405 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1406 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1407 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1408 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base, req.iov[0].iov_base, req.iov[0].iov_len) == 0);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1409 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + req.iov[0].iov_len, req.iov[1].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
1410 : : req.iov[1].iov_len) == 0);
1411 : :
1412 : : /* Test 2 - single user's buffer length equals to chunk_size, buffer is not aligned
1413 : : * User's buffer is copied */
1414 [ + - + - : 3 : req.iov[0].iov_base = unaligned_user_buffer;
+ - + - ]
1415 [ + - + - : 3 : req.iov[0].iov_len = vol.params.chunk_size;
+ - + - +
- ]
1416 [ + - ]: 3 : req.iovcnt = 1;
1417 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1418 : :
1419 : 3 : _prepare_compress_chunk(&req, false);
1420 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1421 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1422 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1423 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base, req.iov[0].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1424 : : req.iov[0].iov_len) == 0);
1425 : :
1426 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1427 : :
1428 : 3 : _prepare_compress_chunk(&req, true);
1429 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1430 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1431 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1432 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base, req.iov[0].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1433 : : req.iov[0].iov_len) == 0);
1434 : :
1435 : : /* Test 3 - single user's buffer length equals to chunk_size
1436 : : * User's buffer is not copied */
1437 [ + - + - : 3 : req.iov[0].iov_base = aligned_user_buffer;
+ - + - ]
1438 [ + - + - : 3 : req.iov[0].iov_len = vol.params.chunk_size;
+ - + - +
- ]
1439 [ + - ]: 3 : req.iovcnt = 1;
1440 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1441 : :
1442 : 3 : _prepare_compress_chunk(&req, false);
1443 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1444 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.iov[0].iov_base);
+ - + - +
- + - + -
+ - ]
1445 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1446 : :
1447 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1448 : :
1449 : 3 : _prepare_compress_chunk(&req, true);
1450 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1451 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.iov[0].iov_base);
+ - + - +
- + - + -
+ - ]
1452 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1453 : :
1454 : : /* Test 4 - user's buffer less than chunk_size, without offset
1455 : : * User's buffers are copied */
1456 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1457 : 3 : user_buffer_iov_len = 4096;
1458 [ + - ]: 3 : req.iovcnt = 2;
1459 [ + - ]: 3 : remainder_bytes = vol.params.chunk_size - user_buffer_iov_len * 2;
1460 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1461 [ + - + - : 6 : req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len;
+ - + - +
- ]
1462 [ + - + - : 6 : req.iov[i].iov_len = user_buffer_iov_len;
+ - + - ]
1463 : 2 : }
1464 : :
1465 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1466 : :
1467 : 3 : _prepare_compress_chunk(&req, false);
1468 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1469 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1470 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1471 : 3 : memcmp_offset = 0;
1472 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[0].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1473 : : req.iov[0].iov_len) == 0);
1474 [ + - + - : 3 : memcmp_offset += req.iov[0].iov_len;
+ - + - ]
1475 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[1].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1476 : : req.iov[1].iov_len) == 0);
1477 [ + - + - : 3 : memcmp_offset += req.iov[0].iov_len;
+ - + - ]
1478 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.decomp_buf + memcmp_offset,
+ - + - +
- + - +
- ]
1479 : : remainder_bytes) == 0);
1480 : :
1481 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1482 : :
1483 : 3 : _prepare_compress_chunk(&req, true);
1484 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1485 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1486 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1487 : 3 : memcmp_offset = 0;
1488 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[0].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1489 : : req.iov[0].iov_len) == 0);
1490 [ + - + - : 3 : memcmp_offset += req.iov[0].iov_len;
+ - + - ]
1491 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[1].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1492 : : req.iov[1].iov_len) == 0);
1493 [ + - + - : 3 : memcmp_offset += req.iov[0].iov_len;
+ - + - ]
1494 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, g_zero_buf + memcmp_offset,
+ - + - +
- + - +
- ]
1495 : : remainder_bytes) == 0);
1496 : :
1497 : : /* Test 5 - user's buffer less than chunk_size, non zero offset
1498 : : * user's buffers are copied */
1499 [ + - ]: 3 : req.offset = 3;
1500 [ + - + - ]: 3 : offset_bytes = req.offset * vol.params.logical_block_size;
1501 [ + - ]: 3 : remainder_bytes = vol.params.chunk_size - offset_bytes - user_buffer_iov_len * 2;
1502 : :
1503 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1504 : :
1505 : 3 : _prepare_compress_chunk(&req, false);
1506 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1507 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1508 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1509 : 3 : memcmp_offset = 0;
1510 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.decomp_buf, offset_bytes) == 0);
+ - + - +
- + - ]
1511 : 3 : memcmp_offset += offset_bytes;
1512 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[0].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1513 : : req.iov[0].iov_len) == 0);
1514 [ + - + - : 3 : memcmp_offset += req.iov[0].iov_len;
+ - + - ]
1515 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[1].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1516 : : req.iov[1].iov_len) == 0);
1517 [ + - + - : 3 : memcmp_offset += req.iov[1].iov_len;
+ - + - ]
1518 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.decomp_buf + memcmp_offset,
+ - + - +
- + - +
- ]
1519 : : remainder_bytes) == 0);
1520 : :
1521 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1522 : :
1523 : 3 : _prepare_compress_chunk(&req, true);
1524 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1525 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1526 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1527 : 3 : memcmp_offset = 0;
1528 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, g_zero_buf, offset_bytes) == 0);
+ - + - +
- + - ]
1529 : 3 : memcmp_offset += offset_bytes;
1530 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[0].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1531 : : req.iov[0].iov_len) == 0);
1532 [ + - + - : 3 : memcmp_offset += req.iov[0].iov_len;
+ - + - ]
1533 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[1].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1534 : : req.iov[1].iov_len) == 0);
1535 [ + - + - : 3 : memcmp_offset += req.iov[1].iov_len;
+ - + - ]
1536 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, g_zero_buf + memcmp_offset,
+ - + - +
- + - +
- ]
1537 : : remainder_bytes) == 0);
1538 : 3 : backing_dev_destroy(&backing_dev);
1539 : 3 : free(buf);
1540 : 3 : }
1541 : :
1542 : : static void
1543 : 24 : _reduce_vol_op_complete(void *ctx, int reduce_errno)
1544 : : {
1545 : 24 : g_reduce_errno = reduce_errno;
1546 : 24 : }
1547 : :
1548 : : static void
1549 : 24 : dummy_backing_dev_decompress(struct spdk_reduce_backing_dev *backing_dev,
1550 : : struct iovec *src_iov, int src_iovcnt,
1551 : : struct iovec *dst_iov, int dst_iovcnt,
1552 : : struct spdk_reduce_vol_cb_args *args)
1553 : : {
1554 [ + - + - ]: 24 : args->output_size = g_decompressed_len;
1555 [ + - + - : 24 : args->cb_fn(args->cb_arg, 0);
- + + - +
- + - ]
1556 : 24 : }
1557 : : static void
1558 : 3 : test_reduce_decompress_chunk(void)
1559 : : {
1560 : 3 : struct spdk_reduce_vol vol = {};
1561 : 3 : struct spdk_reduce_backing_dev backing_dev = {};
1562 : 3 : struct spdk_reduce_vol_request req = {};
1563 : 2 : void *buf;
1564 : 1 : char *buffer_end, *aligned_user_buffer, *unaligned_user_buffer;
1565 : 3 : char decomp_buffer[16 * 1024] = {};
1566 : 3 : char comp_buffer[16 * 1024] = {};
1567 : 3 : struct iovec user_iov[2] = {};
1568 : 3 : struct iovec comp_buf_iov = {};
1569 : 3 : struct spdk_reduce_chunk_map chunk = {};
1570 : 3 : size_t user_buffer_iov_len = 8192;
1571 : 1 : size_t remainder_bytes;
1572 : 1 : size_t offset_bytes;
1573 : 1 : uint32_t i;
1574 : :
1575 [ + - ]: 3 : vol.params.chunk_size = 16 * 1024;
1576 [ + - ]: 3 : vol.params.backing_io_unit_size = 4096;
1577 [ + - ]: 3 : vol.params.logical_block_size = 512;
1578 : 3 : backing_dev_init(&backing_dev, &vol.params, 512);
1579 [ + - ]: 3 : backing_dev.decompress = dummy_backing_dev_decompress;
1580 [ + - ]: 3 : vol.backing_dev = &backing_dev;
1581 [ + + + - : 3 : vol.logical_blocks_per_chunk = vol.params.chunk_size / vol.params.logical_block_size;
+ - + - ]
1582 [ + - + - : 3 : TAILQ_INIT(&vol.executing_requests);
+ - + - +
- ]
1583 [ + - + - : 3 : TAILQ_INIT(&vol.queued_requests);
+ - + - +
- ]
1584 [ + - + - : 3 : TAILQ_INIT(&vol.free_requests);
+ - + - +
- ]
1585 : :
1586 : : /* Allocate 1 extra byte to test a case when buffer crosses huge page boundary */
1587 [ + + + - : 3 : SPDK_CU_ASSERT_FATAL(posix_memalign(&buf, VALUE_2MB, VALUE_2MB + 1) == 0);
+ - + - #
# ]
1588 [ + - + - : 3 : buffer_end = (char *)buf + VALUE_2MB + 1;
+ - ]
1589 : 3 : aligned_user_buffer = (char *)buf;
1590 [ + - + - ]: 3 : unaligned_user_buffer = buffer_end - vol.params.chunk_size;
1591 : :
1592 [ + - ]: 3 : chunk.compressed_size = user_buffer_iov_len / 2;
1593 [ + - ]: 3 : req.chunk = &chunk;
1594 [ + - ]: 3 : req.vol = &vol;
1595 : 3 : req.decomp_buf = decomp_buffer;
1596 [ + - ]: 3 : req.comp_buf = comp_buffer;
1597 [ + - ]: 3 : req.comp_buf_iov = &comp_buf_iov;
1598 [ + - ]: 3 : req.iov = user_iov;
1599 [ + - ]: 3 : req.iovcnt = 2;
1600 [ + - ]: 3 : req.offset = 0;
1601 [ + - ]: 3 : req.cb_fn = _reduce_vol_op_complete;
1602 : :
1603 : : /* Part 1 - backing dev supports sgl_out */
1604 : : /* Test 1 - user's buffers length equals to chunk_size */
1605 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1606 [ + - + - : 6 : req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len;
+ - + - +
- ]
1607 [ + - + - : 6 : req.iov[i].iov_len = user_buffer_iov_len;
+ - + - ]
1608 [ + + + - : 6 : memset(req.iov[i].iov_base, 0, req.iov[i].iov_len);
+ - + - +
- + - + -
+ - + - ]
1609 : 2 : }
1610 [ + + + - : 3 : TAILQ_INSERT_HEAD(&vol.executing_requests, &req, tailq);
+ - + - -
+ # # # #
# # # # #
# # # + -
+ - + - +
- + - + -
+ - + - ]
1611 : 3 : g_reduce_errno = -1;
1612 [ + - ]: 3 : g_decompressed_len = vol.params.chunk_size;
1613 : :
1614 : 3 : _reduce_vol_decompress_chunk(&req, _read_decompress_done);
1615 : 3 : CU_ASSERT(g_reduce_errno == 0);
1616 [ + + ]: 3 : CU_ASSERT(req.copy_after_decompress == false);
1617 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 2);
1618 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1619 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base);
+ - + - +
- + - + -
+ - ]
1620 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
1621 : 2 : }
1622 [ + - + - ]: 3 : CU_ASSERT(TAILQ_EMPTY(&vol.executing_requests));
1623 [ + - + - ]: 3 : CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req);
1624 : :
1625 : : /* Test 2 - user's buffer less than chunk_size, without offset */
1626 [ + + + - : 3 : TAILQ_INSERT_HEAD(&vol.executing_requests, &req, tailq);
+ - + - -
+ # # # #
# # # # #
# # # + -
+ - + - +
- + - + -
+ - + - ]
1627 : 3 : g_reduce_errno = -1;
1628 : 3 : user_buffer_iov_len = 4096;
1629 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1630 [ + - + - : 6 : req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len;
+ - + - +
- ]
1631 [ + - + - : 6 : req.iov[i].iov_len = user_buffer_iov_len;
+ - + - ]
1632 [ + + + - : 6 : memset(req.iov[i].iov_base, 0, req.iov[i].iov_len);
+ - + - +
- + - + -
+ - + - ]
1633 : 2 : }
1634 [ + - ]: 3 : remainder_bytes = vol.params.chunk_size - user_buffer_iov_len * 2;
1635 : :
1636 : 3 : _reduce_vol_decompress_chunk(&req, _read_decompress_done);
1637 : 3 : CU_ASSERT(g_reduce_errno == 0);
1638 [ + + ]: 3 : CU_ASSERT(req.copy_after_decompress == false);
1639 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 3);
1640 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1641 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base);
+ - + - +
- + - + -
+ - ]
1642 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
1643 : 2 : }
1644 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[i].iov_base == req.decomp_buf + user_buffer_iov_len * 2);
+ - + - +
- ]
1645 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[i].iov_len == remainder_bytes);
+ - + - ]
1646 [ + - + - ]: 3 : CU_ASSERT(TAILQ_EMPTY(&vol.executing_requests));
1647 [ + - + - ]: 3 : CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req);
1648 : :
1649 : : /* Test 3 - user's buffer less than chunk_size, non zero offset */
1650 [ + - ]: 3 : req.offset = 3;
1651 [ + - + - ]: 3 : offset_bytes = req.offset * vol.params.logical_block_size;
1652 [ + - ]: 3 : remainder_bytes = vol.params.chunk_size - offset_bytes - user_buffer_iov_len * 2;
1653 [ + + + - : 3 : TAILQ_INSERT_HEAD(&vol.executing_requests, &req, tailq);
+ - + - -
+ # # # #
# # # # #
# # # + -
+ - + - +
- + - + -
+ - + - ]
1654 : 3 : g_reduce_errno = -1;
1655 : :
1656 : 3 : _reduce_vol_decompress_chunk(&req, _read_decompress_done);
1657 : 3 : CU_ASSERT(g_reduce_errno == 0);
1658 [ + + ]: 3 : CU_ASSERT(req.copy_after_decompress == false);
1659 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 4);
1660 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1661 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == offset_bytes);
+ - + - ]
1662 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1663 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i + 1].iov_base == req.iov[i].iov_base);
+ - + - +
- + - + -
+ - ]
1664 [ + - + - : 6 : CU_ASSERT(req.decomp_iov[i + 1].iov_len == req.iov[i].iov_len);
+ - + - +
- + - + -
+ - ]
1665 : 2 : }
1666 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[3].iov_base == req.decomp_buf + offset_bytes + user_buffer_iov_len * 2);
+ - + - +
- + - ]
1667 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[3].iov_len == remainder_bytes);
+ - + - ]
1668 [ + - + - ]: 3 : CU_ASSERT(TAILQ_EMPTY(&vol.executing_requests));
1669 [ + - + - ]: 3 : CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req);
1670 : :
1671 : : /* Part 2 - backing dev doesn't support sgl_out */
1672 : : /* Test 1 - user's buffers length equals to chunk_size
1673 : : * user's buffers are copied */
1674 [ + - + - : 3 : vol.backing_dev->sgl_out = false;
+ - ]
1675 [ + - ]: 3 : req.offset = 0;
1676 : 3 : user_buffer_iov_len = 8192;
1677 : :
1678 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1679 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1680 [ + - + - : 6 : req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len;
+ - + - +
- ]
1681 [ + - + - : 6 : req.iov[i].iov_len = user_buffer_iov_len;
+ - + - ]
1682 [ + + + - : 6 : memset(req.iov[i].iov_base, 0xb + i, req.iov[i].iov_len);
+ - + - +
- + - + -
+ - + - ]
1683 : 2 : }
1684 [ + + + - : 3 : TAILQ_INSERT_HEAD(&vol.executing_requests, &req, tailq);
+ - + - -
+ # # # #
# # # # #
# # # + -
+ - + - +
- + - + -
+ - + - ]
1685 : 3 : g_reduce_errno = -1;
1686 : :
1687 : 3 : _reduce_vol_decompress_chunk(&req, _read_decompress_done);
1688 : 3 : CU_ASSERT(g_reduce_errno == 0);
1689 [ + + ]: 3 : CU_ASSERT(req.copy_after_decompress == true);
1690 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1691 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1692 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1693 [ + + + + : 3 : CU_ASSERT(memcmp(req.iov[0].iov_base, req.decomp_iov[0].iov_base, req.iov[0].iov_len) == 0);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1694 [ + + + + : 3 : CU_ASSERT(memcmp(req.iov[1].iov_base, req.decomp_iov[0].iov_base + req.iov[0].iov_len,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
1695 : : req.iov[1].iov_len) == 0);
1696 [ + - + - ]: 3 : CU_ASSERT(TAILQ_EMPTY(&vol.executing_requests));
1697 [ + - + - ]: 3 : CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req);
1698 : :
1699 : : /* Test 2 - single user's buffer length equals to chunk_size, buffer is not aligned
1700 : : * User's buffer is copied */
1701 [ + + + - ]: 3 : memset(unaligned_user_buffer, 0xc, vol.params.chunk_size);
1702 [ + - + - : 3 : req.iov[0].iov_base = unaligned_user_buffer;
+ - + - ]
1703 [ + - + - : 3 : req.iov[0].iov_len = vol.params.chunk_size;
+ - + - +
- ]
1704 [ + - ]: 3 : req.iovcnt = 1;
1705 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1706 [ + + + - : 3 : TAILQ_INSERT_HEAD(&vol.executing_requests, &req, tailq);
+ - + - -
+ # # # #
# # # # #
# # # + -
+ - + - +
- + - + -
+ - + - ]
1707 : 3 : g_reduce_errno = -1;
1708 : :
1709 : 3 : _reduce_vol_decompress_chunk(&req, _read_decompress_done);
1710 : 3 : CU_ASSERT(g_reduce_errno == 0);
1711 [ + + ]: 3 : CU_ASSERT(req.copy_after_decompress == true);
1712 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1713 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1714 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1715 [ + + + + : 3 : CU_ASSERT(memcmp(req.iov[0].iov_base, req.decomp_iov[0].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1716 : : req.iov[0].iov_len) == 0);
1717 : :
1718 : : /* Test 3 - single user's buffer length equals to chunk_size
1719 : : * User's buffer is not copied */
1720 [ + - + - : 3 : req.iov[0].iov_base = aligned_user_buffer;
+ - + - ]
1721 [ + - + - : 3 : req.iov[0].iov_len = vol.params.chunk_size;
+ - + - +
- ]
1722 [ + - ]: 3 : req.iovcnt = 1;
1723 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1724 [ + + + - : 3 : TAILQ_INSERT_HEAD(&vol.executing_requests, &req, tailq);
+ - + - -
+ # # # #
# # # # #
# # # + -
+ - + - +
- + - + -
+ - + - ]
1725 : 3 : g_reduce_errno = -1;
1726 : :
1727 : 3 : _reduce_vol_decompress_chunk(&req, _read_decompress_done);
1728 : 3 : CU_ASSERT(g_reduce_errno == 0);
1729 [ + + ]: 3 : CU_ASSERT(req.copy_after_decompress == false);
1730 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1731 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.iov[0].iov_base);
+ - + - +
- + - + -
+ - ]
1732 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1733 : :
1734 : : /* Test 4 - user's buffer less than chunk_size, without offset
1735 : : * User's buffers are copied */
1736 : 3 : user_buffer_iov_len = 4096;
1737 [ + - ]: 3 : req.iovcnt = 2;
1738 [ + - ]: 3 : remainder_bytes = vol.params.chunk_size - user_buffer_iov_len * 2;
1739 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1740 [ + - + - : 6 : req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len;
+ - + - +
- ]
1741 [ + - + - : 6 : req.iov[i].iov_len = user_buffer_iov_len;
+ - + - ]
1742 [ + + + - : 6 : memset(req.iov[i].iov_base, 0xb + i, req.iov[i].iov_len);
+ - + - +
- + - + -
+ - + - ]
1743 : 2 : }
1744 : :
1745 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1746 [ + + + - : 3 : TAILQ_INSERT_HEAD(&vol.executing_requests, &req, tailq);
+ - + - -
+ # # # #
# # # # #
# # # + -
+ - + - +
- + - + -
+ - + - ]
1747 : 3 : g_reduce_errno = -1;
1748 : :
1749 : 3 : _reduce_vol_decompress_chunk(&req, _read_decompress_done);
1750 : 3 : CU_ASSERT(g_reduce_errno == 0);
1751 [ + + ]: 3 : CU_ASSERT(req.copy_after_decompress == true);
1752 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1753 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1754 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1755 [ + + + + : 3 : CU_ASSERT(memcmp(req.iov[0].iov_base, req.decomp_iov[0].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1756 : : req.iov[0].iov_len) == 0);
1757 [ + + + + : 3 : CU_ASSERT(memcmp(req.iov[1].iov_base, req.decomp_iov[0].iov_base + req.iov[0].iov_len,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
1758 : : req.iov[1].iov_len) == 0);
1759 [ + - + - ]: 3 : CU_ASSERT(TAILQ_EMPTY(&vol.executing_requests));
1760 [ + - + - ]: 3 : CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req);
1761 : :
1762 : : /* Test 5 - user's buffer less than chunk_size, non zero offset
1763 : : * user's buffers are copied */
1764 [ + - ]: 3 : req.offset = 3;
1765 [ + - + - ]: 3 : offset_bytes = req.offset * vol.params.logical_block_size;
1766 [ + - ]: 3 : remainder_bytes = vol.params.chunk_size - offset_bytes - user_buffer_iov_len * 2;
1767 : :
1768 [ + + ]: 9 : for (i = 0; i < 2; i++) {
1769 [ + - + - : 6 : req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len;
+ - + - +
- ]
1770 [ + - + - : 6 : req.iov[i].iov_len = user_buffer_iov_len;
+ - + - ]
1771 [ + + + - : 6 : memset(req.iov[i].iov_base, 0xb + i, req.iov[i].iov_len);
+ - + - +
- + - + -
+ - + - ]
1772 : 2 : }
1773 : :
1774 [ + + + - ]: 3 : memset(req.decomp_buf, 0xa, vol.params.chunk_size);
1775 [ + + + - : 3 : TAILQ_INSERT_HEAD(&vol.executing_requests, &req, tailq);
+ - + - -
+ # # # #
# # # # #
# # # + -
+ - + - +
- + - + -
+ - + - ]
1776 : 3 : g_reduce_errno = -1;
1777 : :
1778 : 3 : _prepare_compress_chunk(&req, false);
1779 : 3 : _reduce_vol_decompress_chunk(&req, _read_decompress_done);
1780 : 3 : CU_ASSERT(g_reduce_errno == 0);
1781 [ + + ]: 3 : CU_ASSERT(req.copy_after_decompress == true);
1782 [ + - ]: 3 : CU_ASSERT(req.decomp_iovcnt == 1);
1783 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf);
+ - + - ]
1784 [ + - + - : 3 : CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size);
+ - + - +
- ]
1785 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + offset_bytes, req.iov[0].iov_base,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
1786 : : req.iov[0].iov_len) == 0);
1787 [ + + + + : 3 : CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + offset_bytes + req.iov[0].iov_len,
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
1788 : : req.iov[1].iov_base,
1789 : : req.iov[1].iov_len) == 0);
1790 [ + - + - ]: 3 : CU_ASSERT(TAILQ_EMPTY(&vol.executing_requests));
1791 [ + - + - ]: 3 : CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req);
1792 : :
1793 : 3 : free(buf);
1794 : 3 : }
1795 : :
1796 : : static void
1797 : 3 : test_allocate_vol_requests(void)
1798 : : {
1799 : 1 : struct spdk_reduce_vol *vol;
1800 : : /* include chunk_sizes which are not power of 2 */
1801 : 3 : uint32_t chunk_sizes[] = {8192, 8320, 16384, 16416, 32768};
1802 : 3 : uint32_t io_unit_sizes[] = {512, 520, 4096, 4104, 4096};
1803 : 1 : uint32_t i;
1804 : :
1805 [ + + ]: 15 : for (i = 0; i < 4; i++) {
1806 : 12 : vol = calloc(1, sizeof(*vol));
1807 [ + + # # ]: 12 : SPDK_CU_ASSERT_FATAL(vol);
1808 : :
1809 [ + - + - : 12 : vol->params.chunk_size = chunk_sizes[i];
+ - + - +
- + - ]
1810 [ + - + - : 12 : vol->params.logical_block_size = io_unit_sizes[i];
+ - + - +
- + - ]
1811 [ + - + - : 12 : vol->params.backing_io_unit_size = io_unit_sizes[i];
+ - + - +
- + - ]
1812 [ + + + - : 12 : vol->backing_io_units_per_chunk = vol->params.chunk_size / vol->params.backing_io_unit_size;
+ - + - +
- + - + -
+ - + - ]
1813 [ + + + - : 12 : vol->logical_blocks_per_chunk = vol->params.chunk_size / vol->params.logical_block_size;
+ - + - +
- + - + -
+ - + - ]
1814 : :
1815 [ + - ]: 12 : CU_ASSERT(_validate_vol_params(&vol->params) == 0);
1816 : 12 : CU_ASSERT(_allocate_vol_requests(vol) == 0);
1817 : 12 : _init_load_cleanup(vol, NULL);
1818 : 4 : }
1819 : 3 : }
1820 : :
1821 : : int
1822 : 3 : main(int argc, char **argv)
1823 : : {
1824 : 3 : CU_pSuite suite = NULL;
1825 : 1 : unsigned int num_failures;
1826 : :
1827 : 3 : CU_initialize_registry();
1828 : :
1829 : 3 : suite = CU_add_suite("reduce", NULL, NULL);
1830 : :
1831 : 3 : CU_ADD_TEST(suite, get_pm_file_size);
1832 : 3 : CU_ADD_TEST(suite, get_vol_size);
1833 : 3 : CU_ADD_TEST(suite, init_failure);
1834 : 3 : CU_ADD_TEST(suite, init_md);
1835 : 3 : CU_ADD_TEST(suite, init_backing_dev);
1836 : 3 : CU_ADD_TEST(suite, load);
1837 : 3 : CU_ADD_TEST(suite, write_maps);
1838 : 3 : CU_ADD_TEST(suite, read_write);
1839 : 3 : CU_ADD_TEST(suite, readv_writev);
1840 : 3 : CU_ADD_TEST(suite, destroy);
1841 : 3 : CU_ADD_TEST(suite, defer_bdev_io);
1842 : 3 : CU_ADD_TEST(suite, overlapped);
1843 : 3 : CU_ADD_TEST(suite, compress_algorithm);
1844 : 3 : CU_ADD_TEST(suite, test_prepare_compress_chunk);
1845 : 3 : CU_ADD_TEST(suite, test_reduce_decompress_chunk);
1846 : 3 : CU_ADD_TEST(suite, test_allocate_vol_requests);
1847 : :
1848 : 3 : g_unlink_path = g_path;
1849 : 3 : g_unlink_callback = unlink_cb;
1850 : :
1851 : 3 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
1852 : 3 : CU_cleanup_registry();
1853 : 4 : return num_failures;
1854 : 1 : }
|