1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2016 Intel Corporation. 36bf35070SJim Harris * All rights reserved. 442f59f50SAlexey Marchuk * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 56bf35070SJim Harris */ 66bf35070SJim Harris 76bf35070SJim Harris #include "spdk/stdinc.h" 86bf35070SJim Harris 9ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h" 106bf35070SJim Harris 116bf35070SJim Harris #include "reduce/reduce.c" 12dfd44de7SJim Harris #include "spdk_internal/mock.h" 13b86e85f5SAlexey Marchuk #define UNIT_TEST_NO_VTOPHYS 146bf35070SJim Harris #include "common/lib/test_env.c" 15*412fced1SYalong Wang #include "thread/thread_internal.h" 16b86e85f5SAlexey Marchuk #undef UNIT_TEST_NO_VTOPHYS 176bf35070SJim Harris 18f28f8133SJim Harris static struct spdk_reduce_vol *g_vol; 193213962eSJim Harris static int g_reduce_errno; 20dfd44de7SJim Harris static char *g_volatile_pm_buf; 21d31f2be5SJim Harris static size_t g_volatile_pm_buf_len; 22dfd44de7SJim Harris static char *g_persistent_pm_buf; 231d75aad3SJim Harris static size_t g_persistent_pm_buf_len; 24b7623dd4SJim Harris static char *g_backing_dev_buf; 25c887a4f9SJim Harris static char g_path[REDUCE_PATH_MAX]; 262b336507Spaul luse static char *g_decomp_buf; 2742f59f50SAlexey Marchuk static int g_decompressed_len; 28dfd44de7SJim Harris 29d31f2be5SJim Harris #define TEST_MD_PATH "/tmp" 30cfc372c2SJim Harris 31b86e85f5SAlexey Marchuk uint64_t 32b86e85f5SAlexey Marchuk spdk_vtophys(const void *buf, uint64_t *size) 33b86e85f5SAlexey Marchuk { 34b86e85f5SAlexey Marchuk /* add + 1 to buf addr for cases where buf is the start of the page, that will give us correct end of the page */ 35b86e85f5SAlexey Marchuk const uint8_t *page_2mb_end = (const uint8_t *)SPDK_ALIGN_CEIL((uintptr_t)buf + 1, VALUE_2MB); 36b86e85f5SAlexey Marchuk uint64_t bytes_to_page_end = page_2mb_end - (const uint8_t *)buf; 37b86e85f5SAlexey Marchuk uint64_t _size; 38b86e85f5SAlexey Marchuk 39b86e85f5SAlexey Marchuk if (*size) { 40b86e85f5SAlexey Marchuk _size = *size; 41b86e85f5SAlexey Marchuk _size = spdk_min(_size, bytes_to_page_end); 42b86e85f5SAlexey Marchuk *size = _size; 43b86e85f5SAlexey Marchuk } 44b86e85f5SAlexey Marchuk 45b86e85f5SAlexey Marchuk return (uintptr_t)buf; 46b86e85f5SAlexey Marchuk } 47b86e85f5SAlexey Marchuk 4894d353eaSJim Harris enum ut_reduce_bdev_io_type { 4994d353eaSJim Harris UT_REDUCE_IO_READV = 1, 5094d353eaSJim Harris UT_REDUCE_IO_WRITEV = 2, 5194d353eaSJim Harris UT_REDUCE_IO_UNMAP = 3, 5294d353eaSJim Harris }; 5394d353eaSJim Harris 5494d353eaSJim Harris struct ut_reduce_bdev_io { 5594d353eaSJim Harris enum ut_reduce_bdev_io_type type; 5694d353eaSJim Harris struct spdk_reduce_backing_dev *backing_dev; 5794d353eaSJim Harris struct iovec *iov; 5894d353eaSJim Harris int iovcnt; 5994d353eaSJim Harris uint64_t lba; 6094d353eaSJim Harris uint32_t lba_count; 6194d353eaSJim Harris struct spdk_reduce_vol_cb_args *args; 6294d353eaSJim Harris TAILQ_ENTRY(ut_reduce_bdev_io) link; 6394d353eaSJim Harris }; 6494d353eaSJim Harris 6594d353eaSJim Harris static bool g_defer_bdev_io = false; 6694d353eaSJim Harris static TAILQ_HEAD(, ut_reduce_bdev_io) g_pending_bdev_io = 6794d353eaSJim Harris TAILQ_HEAD_INITIALIZER(g_pending_bdev_io); 6894d353eaSJim Harris static uint32_t g_pending_bdev_io_count = 0; 69*412fced1SYalong Wang static struct spdk_thread *g_thread = NULL; 7094d353eaSJim Harris 71dfd44de7SJim Harris static void 72dfd44de7SJim Harris sync_pm_buf(const void *addr, size_t length) 73dfd44de7SJim Harris { 74dfd44de7SJim Harris uint64_t offset = (char *)addr - g_volatile_pm_buf; 75dfd44de7SJim Harris 76dfd44de7SJim Harris memcpy(&g_persistent_pm_buf[offset], addr, length); 77dfd44de7SJim Harris } 78dfd44de7SJim Harris 79dfd44de7SJim Harris int 80dfd44de7SJim Harris pmem_msync(const void *addr, size_t length) 81dfd44de7SJim Harris { 82dfd44de7SJim Harris sync_pm_buf(addr, length); 83dfd44de7SJim Harris return 0; 84dfd44de7SJim Harris } 85dfd44de7SJim Harris 86dfd44de7SJim Harris void 87dfd44de7SJim Harris pmem_persist(const void *addr, size_t len) 88dfd44de7SJim Harris { 89dfd44de7SJim Harris sync_pm_buf(addr, len); 90dfd44de7SJim Harris } 91f28f8133SJim Harris 926bf35070SJim Harris static void 93dd42c808SJim Harris get_pm_file_size(void) 946bf35070SJim Harris { 95dd42c808SJim Harris struct spdk_reduce_vol_params params; 960b0af8f3SJim Harris uint64_t pm_size, expected_pm_size; 97dd42c808SJim Harris 98dd42c808SJim Harris params.backing_io_unit_size = 4096; 99dd42c808SJim Harris params.chunk_size = 4096 * 4; 100dd42c808SJim Harris params.vol_size = 4096 * 4 * 100; 1010b0af8f3SJim Harris 1020b0af8f3SJim Harris pm_size = _get_pm_file_size(¶ms); 103dd42c808SJim Harris expected_pm_size = sizeof(struct spdk_reduce_vol_superblock); 104dd42c808SJim Harris /* 100 chunks in logical map * 8 bytes per chunk */ 105dd42c808SJim Harris expected_pm_size += 100 * sizeof(uint64_t); 106c9c7c281SJosh Soref /* 100 chunks * (chunk struct size + 4 backing io units per chunk * 8 bytes per backing io unit) */ 107cc6314a4Spaul luse expected_pm_size += 100 * (sizeof(struct spdk_reduce_chunk_map) + 4 * sizeof(uint64_t)); 108dd42c808SJim Harris /* reduce allocates some extra chunks too for in-flight writes when logical map 109cc6314a4Spaul luse * is full. REDUCE_EXTRA_CHUNKS is a private #ifdef in reduce.c Here we need the num chunks 110cc6314a4Spaul luse * times (chunk struct size + 4 backing io units per chunk * 8 bytes per backing io unit). 111dd42c808SJim Harris */ 112cc6314a4Spaul luse expected_pm_size += REDUCE_NUM_EXTRA_CHUNKS * 113cc6314a4Spaul luse (sizeof(struct spdk_reduce_chunk_map) + 4 * sizeof(uint64_t)); 114dd42c808SJim Harris /* reduce will add some padding so numbers may not match exactly. Make sure 115dd42c808SJim Harris * they are close though. 116dd42c808SJim Harris */ 117cc6314a4Spaul luse CU_ASSERT((pm_size - expected_pm_size) <= REDUCE_PM_SIZE_ALIGNMENT); 118dd42c808SJim Harris } 119dd42c808SJim Harris 120dd42c808SJim Harris static void 1210b0af8f3SJim Harris get_vol_size(void) 122dd42c808SJim Harris { 1230b0af8f3SJim Harris uint64_t chunk_size, backing_dev_size; 124dd42c808SJim Harris 1250b0af8f3SJim Harris chunk_size = 16 * 1024; 1260b0af8f3SJim Harris backing_dev_size = 16 * 1024 * 1000; 1270b0af8f3SJim Harris CU_ASSERT(_get_vol_size(chunk_size, backing_dev_size) < backing_dev_size); 1286bf35070SJim Harris } 1296bf35070SJim Harris 130d31f2be5SJim Harris void * 131d31f2be5SJim Harris pmem_map_file(const char *path, size_t len, int flags, mode_t mode, 132d31f2be5SJim Harris size_t *mapped_lenp, int *is_pmemp) 133c6323a8dSJim Harris { 134d31f2be5SJim Harris CU_ASSERT(g_volatile_pm_buf == NULL); 135c887a4f9SJim Harris snprintf(g_path, sizeof(g_path), "%s", path); 136d31f2be5SJim Harris *is_pmemp = 1; 137d31f2be5SJim Harris 138d31f2be5SJim Harris if (g_persistent_pm_buf == NULL) { 139d31f2be5SJim Harris g_persistent_pm_buf = calloc(1, len); 1401d75aad3SJim Harris g_persistent_pm_buf_len = len; 141d31f2be5SJim Harris SPDK_CU_ASSERT_FATAL(g_persistent_pm_buf != NULL); 142d31f2be5SJim Harris } 143d31f2be5SJim Harris 1441d75aad3SJim Harris *mapped_lenp = g_persistent_pm_buf_len; 1451d75aad3SJim Harris g_volatile_pm_buf = calloc(1, g_persistent_pm_buf_len); 1461d75aad3SJim Harris SPDK_CU_ASSERT_FATAL(g_volatile_pm_buf != NULL); 14763ba545fSJim Harris memcpy(g_volatile_pm_buf, g_persistent_pm_buf, g_persistent_pm_buf_len); 1481d75aad3SJim Harris g_volatile_pm_buf_len = g_persistent_pm_buf_len; 1491d75aad3SJim Harris 150d31f2be5SJim Harris return g_volatile_pm_buf; 151d31f2be5SJim Harris } 152d31f2be5SJim Harris 153d31f2be5SJim Harris int 154d31f2be5SJim Harris pmem_unmap(void *addr, size_t len) 155d31f2be5SJim Harris { 156d31f2be5SJim Harris CU_ASSERT(addr == g_volatile_pm_buf); 157d31f2be5SJim Harris CU_ASSERT(len == g_volatile_pm_buf_len); 158c6323a8dSJim Harris free(g_volatile_pm_buf); 159c6323a8dSJim Harris g_volatile_pm_buf = NULL; 1601d75aad3SJim Harris g_volatile_pm_buf_len = 0; 161d31f2be5SJim Harris 162d31f2be5SJim Harris return 0; 163c6323a8dSJim Harris } 164c6323a8dSJim Harris 165c6323a8dSJim Harris static void 166d31f2be5SJim Harris persistent_pm_buf_destroy(void) 167c6323a8dSJim Harris { 168c6323a8dSJim Harris CU_ASSERT(g_persistent_pm_buf != NULL); 169c6323a8dSJim Harris free(g_persistent_pm_buf); 170c6323a8dSJim Harris g_persistent_pm_buf = NULL; 1711d75aad3SJim Harris g_persistent_pm_buf_len = 0; 172c6323a8dSJim Harris } 173c6323a8dSJim Harris 174cfb65ba6SJim Harris static void 175cfb65ba6SJim Harris unlink_cb(void) 176c0f38051SJim Harris { 177c0f38051SJim Harris persistent_pm_buf_destroy(); 178c0f38051SJim Harris } 179c0f38051SJim Harris 180f28f8133SJim Harris static void 1813213962eSJim Harris init_cb(void *cb_arg, struct spdk_reduce_vol *vol, int reduce_errno) 182f28f8133SJim Harris { 183f28f8133SJim Harris g_vol = vol; 1843213962eSJim Harris g_reduce_errno = reduce_errno; 185f28f8133SJim Harris } 186f28f8133SJim Harris 187f28f8133SJim Harris static void 1883213962eSJim Harris load_cb(void *cb_arg, struct spdk_reduce_vol *vol, int reduce_errno) 189eebdab61SJim Harris { 190eebdab61SJim Harris g_vol = vol; 1913213962eSJim Harris g_reduce_errno = reduce_errno; 192eebdab61SJim Harris } 193eebdab61SJim Harris 194eebdab61SJim Harris static void 1953213962eSJim Harris unload_cb(void *cb_arg, int reduce_errno) 196f28f8133SJim Harris { 1973213962eSJim Harris g_reduce_errno = reduce_errno; 198f28f8133SJim Harris } 199f28f8133SJim Harris 200f28f8133SJim Harris static void 201649a585fSJim Harris init_failure(void) 202f28f8133SJim Harris { 203f28f8133SJim Harris struct spdk_reduce_vol_params params = {}; 204f28f8133SJim Harris struct spdk_reduce_backing_dev backing_dev = {}; 205f28f8133SJim Harris 206f28f8133SJim Harris backing_dev.blocklen = 512; 2070b0af8f3SJim Harris /* This blockcnt is too small for a reduce vol - there needs to be 2080b0af8f3SJim Harris * enough space for at least REDUCE_NUM_EXTRA_CHUNKS + 1 chunks. 2090b0af8f3SJim Harris */ 2100b0af8f3SJim Harris backing_dev.blockcnt = 20; 211f28f8133SJim Harris 2120b0af8f3SJim Harris params.vol_size = 0; 213f28f8133SJim Harris params.chunk_size = 16 * 1024; 214f28f8133SJim Harris params.backing_io_unit_size = backing_dev.blocklen; 2155ae61d42SJim Harris params.logical_block_size = 512; 216f28f8133SJim Harris 2170b0af8f3SJim Harris /* backing_dev has an invalid size. This should fail. */ 218f28f8133SJim Harris g_vol = NULL; 2193213962eSJim Harris g_reduce_errno = 0; 220d31f2be5SJim Harris spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 2213213962eSJim Harris CU_ASSERT(g_reduce_errno == -EINVAL); 222f28f8133SJim Harris SPDK_CU_ASSERT_FATAL(g_vol == NULL); 223f28f8133SJim Harris 224d31f2be5SJim Harris /* backing_dev now has valid size, but backing_dev still has null 225d31f2be5SJim Harris * function pointers. This should fail. 226f28f8133SJim Harris */ 2270b0af8f3SJim Harris backing_dev.blockcnt = 20000; 228f28f8133SJim Harris 229f28f8133SJim Harris g_vol = NULL; 2303213962eSJim Harris g_reduce_errno = 0; 231d31f2be5SJim Harris spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 2323213962eSJim Harris CU_ASSERT(g_reduce_errno == -EINVAL); 233f28f8133SJim Harris SPDK_CU_ASSERT_FATAL(g_vol == NULL); 234dfd44de7SJim Harris } 235dfd44de7SJim Harris 236dfd44de7SJim Harris static void 237670db760SJim Harris backing_dev_readv_execute(struct spdk_reduce_backing_dev *backing_dev, 238670db760SJim Harris struct iovec *iov, int iovcnt, 239670db760SJim Harris uint64_t lba, uint32_t lba_count, 240670db760SJim Harris struct spdk_reduce_vol_cb_args *args) 241b7623dd4SJim Harris { 242b7623dd4SJim Harris char *offset; 243b7623dd4SJim Harris int i; 244b7623dd4SJim Harris 245b7623dd4SJim Harris offset = g_backing_dev_buf + lba * backing_dev->blocklen; 246b7623dd4SJim Harris for (i = 0; i < iovcnt; i++) { 247b7623dd4SJim Harris memcpy(iov[i].iov_base, offset, iov[i].iov_len); 248b7623dd4SJim Harris offset += iov[i].iov_len; 249b7623dd4SJim Harris } 250b7623dd4SJim Harris args->cb_fn(args->cb_arg, 0); 251b7623dd4SJim Harris } 252b7623dd4SJim Harris 253b7623dd4SJim Harris static void 25494d353eaSJim Harris backing_dev_insert_io(enum ut_reduce_bdev_io_type type, struct spdk_reduce_backing_dev *backing_dev, 25594d353eaSJim Harris struct iovec *iov, int iovcnt, uint64_t lba, uint32_t lba_count, 25694d353eaSJim Harris struct spdk_reduce_vol_cb_args *args) 25794d353eaSJim Harris { 25894d353eaSJim Harris struct ut_reduce_bdev_io *ut_bdev_io; 25994d353eaSJim Harris 26094d353eaSJim Harris ut_bdev_io = calloc(1, sizeof(*ut_bdev_io)); 26194d353eaSJim Harris SPDK_CU_ASSERT_FATAL(ut_bdev_io != NULL); 26294d353eaSJim Harris 26394d353eaSJim Harris ut_bdev_io->type = type; 26494d353eaSJim Harris ut_bdev_io->backing_dev = backing_dev; 26594d353eaSJim Harris ut_bdev_io->iov = iov; 26694d353eaSJim Harris ut_bdev_io->iovcnt = iovcnt; 26794d353eaSJim Harris ut_bdev_io->lba = lba; 26894d353eaSJim Harris ut_bdev_io->lba_count = lba_count; 26994d353eaSJim Harris ut_bdev_io->args = args; 27094d353eaSJim Harris TAILQ_INSERT_TAIL(&g_pending_bdev_io, ut_bdev_io, link); 27194d353eaSJim Harris g_pending_bdev_io_count++; 27294d353eaSJim Harris } 27394d353eaSJim Harris 27494d353eaSJim Harris static void 275670db760SJim Harris backing_dev_readv(struct spdk_reduce_backing_dev *backing_dev, struct iovec *iov, int iovcnt, 276b7623dd4SJim Harris uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args) 277b7623dd4SJim Harris { 27894d353eaSJim Harris if (g_defer_bdev_io == false) { 27994d353eaSJim Harris CU_ASSERT(g_pending_bdev_io_count == 0); 28094d353eaSJim Harris CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io)); 281670db760SJim Harris backing_dev_readv_execute(backing_dev, iov, iovcnt, lba, lba_count, args); 28294d353eaSJim Harris return; 28394d353eaSJim Harris } 28494d353eaSJim Harris 28594d353eaSJim Harris backing_dev_insert_io(UT_REDUCE_IO_READV, backing_dev, iov, iovcnt, lba, lba_count, args); 286670db760SJim Harris } 287670db760SJim Harris 288670db760SJim Harris static void 289670db760SJim Harris backing_dev_writev_execute(struct spdk_reduce_backing_dev *backing_dev, 290670db760SJim Harris struct iovec *iov, int iovcnt, 291670db760SJim Harris uint64_t lba, uint32_t lba_count, 292670db760SJim Harris struct spdk_reduce_vol_cb_args *args) 293670db760SJim Harris { 294b7623dd4SJim Harris char *offset; 295b7623dd4SJim Harris int i; 296b7623dd4SJim Harris 297b7623dd4SJim Harris offset = g_backing_dev_buf + lba * backing_dev->blocklen; 298b7623dd4SJim Harris for (i = 0; i < iovcnt; i++) { 299b7623dd4SJim Harris memcpy(offset, iov[i].iov_base, iov[i].iov_len); 300b7623dd4SJim Harris offset += iov[i].iov_len; 301b7623dd4SJim Harris } 302b7623dd4SJim Harris args->cb_fn(args->cb_arg, 0); 303b7623dd4SJim Harris } 304b7623dd4SJim Harris 305b7623dd4SJim Harris static void 306670db760SJim Harris backing_dev_writev(struct spdk_reduce_backing_dev *backing_dev, struct iovec *iov, int iovcnt, 307b7623dd4SJim Harris uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args) 308b7623dd4SJim Harris { 30994d353eaSJim Harris if (g_defer_bdev_io == false) { 31094d353eaSJim Harris CU_ASSERT(g_pending_bdev_io_count == 0); 31194d353eaSJim Harris CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io)); 312670db760SJim Harris backing_dev_writev_execute(backing_dev, iov, iovcnt, lba, lba_count, args); 31394d353eaSJim Harris return; 31494d353eaSJim Harris } 31594d353eaSJim Harris 31694d353eaSJim Harris backing_dev_insert_io(UT_REDUCE_IO_WRITEV, backing_dev, iov, iovcnt, lba, lba_count, args); 317670db760SJim Harris } 318670db760SJim Harris 319670db760SJim Harris static void 320670db760SJim Harris backing_dev_unmap_execute(struct spdk_reduce_backing_dev *backing_dev, 321670db760SJim Harris uint64_t lba, uint32_t lba_count, 322670db760SJim Harris struct spdk_reduce_vol_cb_args *args) 323670db760SJim Harris { 324b7623dd4SJim Harris char *offset; 325b7623dd4SJim Harris 326b7623dd4SJim Harris offset = g_backing_dev_buf + lba * backing_dev->blocklen; 327b7623dd4SJim Harris memset(offset, 0, lba_count * backing_dev->blocklen); 328b7623dd4SJim Harris args->cb_fn(args->cb_arg, 0); 329b7623dd4SJim Harris } 330b7623dd4SJim Harris 331b7623dd4SJim Harris static void 332670db760SJim Harris backing_dev_unmap(struct spdk_reduce_backing_dev *backing_dev, 333670db760SJim Harris uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args) 334670db760SJim Harris { 33594d353eaSJim Harris if (g_defer_bdev_io == false) { 33694d353eaSJim Harris CU_ASSERT(g_pending_bdev_io_count == 0); 33794d353eaSJim Harris CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io)); 338670db760SJim Harris backing_dev_unmap_execute(backing_dev, lba, lba_count, args); 33994d353eaSJim Harris return; 34094d353eaSJim Harris } 34194d353eaSJim Harris 34294d353eaSJim Harris backing_dev_insert_io(UT_REDUCE_IO_UNMAP, backing_dev, NULL, 0, lba, lba_count, args); 34394d353eaSJim Harris } 34494d353eaSJim Harris 34594d353eaSJim Harris static void 34694d353eaSJim Harris backing_dev_io_execute(uint32_t count) 34794d353eaSJim Harris { 34894d353eaSJim Harris struct ut_reduce_bdev_io *ut_bdev_io; 34994d353eaSJim Harris uint32_t done = 0; 35094d353eaSJim Harris 35194d353eaSJim Harris CU_ASSERT(g_defer_bdev_io == true); 35294d353eaSJim Harris while (!TAILQ_EMPTY(&g_pending_bdev_io) && (count == 0 || done < count)) { 35394d353eaSJim Harris ut_bdev_io = TAILQ_FIRST(&g_pending_bdev_io); 35494d353eaSJim Harris TAILQ_REMOVE(&g_pending_bdev_io, ut_bdev_io, link); 35594d353eaSJim Harris g_pending_bdev_io_count--; 35694d353eaSJim Harris switch (ut_bdev_io->type) { 35794d353eaSJim Harris case UT_REDUCE_IO_READV: 35894d353eaSJim Harris backing_dev_readv_execute(ut_bdev_io->backing_dev, 35994d353eaSJim Harris ut_bdev_io->iov, ut_bdev_io->iovcnt, 36094d353eaSJim Harris ut_bdev_io->lba, ut_bdev_io->lba_count, 36194d353eaSJim Harris ut_bdev_io->args); 36294d353eaSJim Harris break; 36394d353eaSJim Harris case UT_REDUCE_IO_WRITEV: 36494d353eaSJim Harris backing_dev_writev_execute(ut_bdev_io->backing_dev, 36594d353eaSJim Harris ut_bdev_io->iov, ut_bdev_io->iovcnt, 36694d353eaSJim Harris ut_bdev_io->lba, ut_bdev_io->lba_count, 36794d353eaSJim Harris ut_bdev_io->args); 36894d353eaSJim Harris break; 36994d353eaSJim Harris case UT_REDUCE_IO_UNMAP: 37094d353eaSJim Harris backing_dev_unmap_execute(ut_bdev_io->backing_dev, 37194d353eaSJim Harris ut_bdev_io->lba, ut_bdev_io->lba_count, 37294d353eaSJim Harris ut_bdev_io->args); 37394d353eaSJim Harris break; 37494d353eaSJim Harris default: 37594d353eaSJim Harris CU_ASSERT(false); 37694d353eaSJim Harris break; 37794d353eaSJim Harris } 37894d353eaSJim Harris free(ut_bdev_io); 37994d353eaSJim Harris done++; 38094d353eaSJim Harris } 381670db760SJim Harris } 382670db760SJim Harris 383245271b6SYankun Li static void 384245271b6SYankun Li backing_dev_submit_io(struct spdk_reduce_backing_io *backing_io) 385245271b6SYankun Li { 386245271b6SYankun Li switch (backing_io->backing_io_type) { 387245271b6SYankun Li case SPDK_REDUCE_BACKING_IO_WRITE: 388245271b6SYankun Li backing_dev_writev(backing_io->dev, backing_io->iov, backing_io->iovcnt, 389245271b6SYankun Li backing_io->lba, backing_io->lba_count, backing_io->backing_cb_args); 390245271b6SYankun Li break; 391245271b6SYankun Li case SPDK_REDUCE_BACKING_IO_READ: 392245271b6SYankun Li backing_dev_readv(backing_io->dev, backing_io->iov, backing_io->iovcnt, 393245271b6SYankun Li backing_io->lba, backing_io->lba_count, backing_io->backing_cb_args); 394245271b6SYankun Li break; 395245271b6SYankun Li case SPDK_REDUCE_BACKING_IO_UNMAP: 396245271b6SYankun Li backing_dev_unmap(backing_io->dev, backing_io->lba, backing_io->lba_count, 397245271b6SYankun Li backing_io->backing_cb_args); 398245271b6SYankun Li break; 399245271b6SYankun Li default: 400245271b6SYankun Li CU_ASSERT(false); 401245271b6SYankun Li break; 402245271b6SYankun Li } 403245271b6SYankun Li } 404245271b6SYankun Li 40527631eb5SJim Harris static int 40627631eb5SJim Harris ut_compress(char *outbuf, uint32_t *compressed_len, char *inbuf, uint32_t inbuflen) 40727631eb5SJim Harris { 40827631eb5SJim Harris uint32_t len = 0; 40927631eb5SJim Harris uint8_t count; 41027631eb5SJim Harris char last; 41127631eb5SJim Harris 41227631eb5SJim Harris while (true) { 41327631eb5SJim Harris if (inbuflen == 0) { 41427631eb5SJim Harris *compressed_len = len; 41527631eb5SJim Harris return 0; 41627631eb5SJim Harris } 41727631eb5SJim Harris 41827631eb5SJim Harris if (*compressed_len < (len + 2)) { 41927631eb5SJim Harris return -ENOSPC; 42027631eb5SJim Harris } 42127631eb5SJim Harris 42227631eb5SJim Harris last = *inbuf; 42327631eb5SJim Harris count = 1; 42427631eb5SJim Harris inbuflen--; 42527631eb5SJim Harris inbuf++; 42627631eb5SJim Harris 42727631eb5SJim Harris while (inbuflen > 0 && *inbuf == last && count < UINT8_MAX) { 42827631eb5SJim Harris count++; 42927631eb5SJim Harris inbuflen--; 43027631eb5SJim Harris inbuf++; 43127631eb5SJim Harris } 43227631eb5SJim Harris 43327631eb5SJim Harris outbuf[len] = count; 43427631eb5SJim Harris outbuf[len + 1] = last; 43527631eb5SJim Harris len += 2; 43627631eb5SJim Harris } 43727631eb5SJim Harris } 43827631eb5SJim Harris 43927631eb5SJim Harris static int 44027631eb5SJim Harris ut_decompress(uint8_t *outbuf, uint32_t *compressed_len, uint8_t *inbuf, uint32_t inbuflen) 44127631eb5SJim Harris { 44227631eb5SJim Harris uint32_t len = 0; 44327631eb5SJim Harris 44427631eb5SJim Harris SPDK_CU_ASSERT_FATAL(inbuflen % 2 == 0); 44527631eb5SJim Harris 44627631eb5SJim Harris while (true) { 44727631eb5SJim Harris if (inbuflen == 0) { 44827631eb5SJim Harris *compressed_len = len; 44927631eb5SJim Harris return 0; 45027631eb5SJim Harris } 45127631eb5SJim Harris 45227631eb5SJim Harris if ((len + inbuf[0]) > *compressed_len) { 45327631eb5SJim Harris return -ENOSPC; 45427631eb5SJim Harris } 45527631eb5SJim Harris 45627631eb5SJim Harris memset(outbuf, inbuf[1], inbuf[0]); 45727631eb5SJim Harris outbuf += inbuf[0]; 45827631eb5SJim Harris len += inbuf[0]; 45927631eb5SJim Harris inbuflen -= 2; 46027631eb5SJim Harris inbuf += 2; 46127631eb5SJim Harris } 46227631eb5SJim Harris } 46327631eb5SJim Harris 46427631eb5SJim Harris static void 46527631eb5SJim Harris ut_build_data_buffer(uint8_t *data, uint32_t data_len, uint8_t init_val, uint32_t repeat) 46627631eb5SJim Harris { 46727631eb5SJim Harris uint32_t _repeat = repeat; 46827631eb5SJim Harris 46927631eb5SJim Harris SPDK_CU_ASSERT_FATAL(repeat > 0); 47027631eb5SJim Harris 47127631eb5SJim Harris while (data_len > 0) { 47227631eb5SJim Harris *data = init_val; 47327631eb5SJim Harris data++; 47427631eb5SJim Harris data_len--; 47527631eb5SJim Harris _repeat--; 47627631eb5SJim Harris if (_repeat == 0) { 47727631eb5SJim Harris init_val++; 47827631eb5SJim Harris _repeat = repeat; 47927631eb5SJim Harris } 48027631eb5SJim Harris } 48127631eb5SJim Harris } 48227631eb5SJim Harris 483670db760SJim Harris static void 484309f7791SJim Harris backing_dev_compress(struct spdk_reduce_backing_dev *backing_dev, 485309f7791SJim Harris struct iovec *src_iov, int src_iovcnt, 486309f7791SJim Harris struct iovec *dst_iov, int dst_iovcnt, 487309f7791SJim Harris struct spdk_reduce_vol_cb_args *args) 488309f7791SJim Harris { 4891679104eSJim Harris uint32_t compressed_len; 4902b336507Spaul luse uint64_t total_length = 0; 4912b336507Spaul luse char *buf = g_decomp_buf; 4922b336507Spaul luse int rc, i; 4931679104eSJim Harris 494309f7791SJim Harris CU_ASSERT(dst_iovcnt == 1); 4952b336507Spaul luse 4962b336507Spaul luse for (i = 0; i < src_iovcnt; i++) { 4972b336507Spaul luse memcpy(buf, src_iov[i].iov_base, src_iov[i].iov_len); 4982b336507Spaul luse buf += src_iov[i].iov_len; 4992b336507Spaul luse total_length += src_iov[i].iov_len; 5002b336507Spaul luse } 5011679104eSJim Harris 5021679104eSJim Harris compressed_len = dst_iov[0].iov_len; 5031679104eSJim Harris rc = ut_compress(dst_iov[0].iov_base, &compressed_len, 5042b336507Spaul luse g_decomp_buf, total_length); 5052b336507Spaul luse 506bb5083a8Spaul luse args->output_size = compressed_len; 507bb5083a8Spaul luse 508bb5083a8Spaul luse args->cb_fn(args->cb_arg, rc); 509309f7791SJim Harris } 510309f7791SJim Harris 511309f7791SJim Harris static void 512309f7791SJim Harris backing_dev_decompress(struct spdk_reduce_backing_dev *backing_dev, 513309f7791SJim Harris struct iovec *src_iov, int src_iovcnt, 514309f7791SJim Harris struct iovec *dst_iov, int dst_iovcnt, 515309f7791SJim Harris struct spdk_reduce_vol_cb_args *args) 516309f7791SJim Harris { 5172b336507Spaul luse uint32_t decompressed_len = 0; 5182b336507Spaul luse char *buf = g_decomp_buf; 5192b336507Spaul luse int rc, i; 5201679104eSJim Harris 521309f7791SJim Harris CU_ASSERT(src_iovcnt == 1); 5221679104eSJim Harris 5232b336507Spaul luse for (i = 0; i < dst_iovcnt; i++) { 5242b336507Spaul luse decompressed_len += dst_iov[i].iov_len; 5252b336507Spaul luse } 5262b336507Spaul luse 5272b336507Spaul luse rc = ut_decompress(g_decomp_buf, &decompressed_len, 5281679104eSJim Harris src_iov[0].iov_base, src_iov[0].iov_len); 5292b336507Spaul luse 5302b336507Spaul luse for (i = 0; i < dst_iovcnt; i++) { 5312b336507Spaul luse memcpy(dst_iov[i].iov_base, buf, dst_iov[i].iov_len); 5322b336507Spaul luse buf += dst_iov[i].iov_len; 5332b336507Spaul luse } 5342b336507Spaul luse 535bb5083a8Spaul luse args->output_size = decompressed_len; 536bb5083a8Spaul luse 537bb5083a8Spaul luse args->cb_fn(args->cb_arg, rc); 538309f7791SJim Harris } 539309f7791SJim Harris 540309f7791SJim Harris static void 541b7623dd4SJim Harris backing_dev_destroy(struct spdk_reduce_backing_dev *backing_dev) 542b7623dd4SJim Harris { 543b7623dd4SJim Harris /* We don't free this during backing_dev_close so that we can test init/unload/load 544b7623dd4SJim Harris * scenarios. 545b7623dd4SJim Harris */ 546b7623dd4SJim Harris free(g_backing_dev_buf); 5472b336507Spaul luse free(g_decomp_buf); 548b7623dd4SJim Harris g_backing_dev_buf = NULL; 549b7623dd4SJim Harris } 550b7623dd4SJim Harris 551b7623dd4SJim Harris static void 552212770dbSJim Harris backing_dev_init(struct spdk_reduce_backing_dev *backing_dev, struct spdk_reduce_vol_params *params, 553212770dbSJim Harris uint32_t backing_blocklen) 5543981ba69SJim Harris { 555b7623dd4SJim Harris int64_t size; 556b7623dd4SJim Harris 5570b0af8f3SJim Harris size = 4 * 1024 * 1024; 558212770dbSJim Harris backing_dev->blocklen = backing_blocklen; 559b7623dd4SJim Harris backing_dev->blockcnt = size / backing_dev->blocklen; 560245271b6SYankun Li backing_dev->submit_backing_io = backing_dev_submit_io; 561309f7791SJim Harris backing_dev->compress = backing_dev_compress; 562309f7791SJim Harris backing_dev->decompress = backing_dev_decompress; 56342f59f50SAlexey Marchuk backing_dev->sgl_in = true; 56442f59f50SAlexey Marchuk backing_dev->sgl_out = true; 565b7623dd4SJim Harris 5662b336507Spaul luse g_decomp_buf = calloc(1, params->chunk_size); 5672b336507Spaul luse SPDK_CU_ASSERT_FATAL(g_decomp_buf != NULL); 5682b336507Spaul luse 569b7623dd4SJim Harris g_backing_dev_buf = calloc(1, size); 570b7623dd4SJim Harris SPDK_CU_ASSERT_FATAL(g_backing_dev_buf != NULL); 5713981ba69SJim Harris } 5723981ba69SJim Harris 5733981ba69SJim Harris static void 574dfd44de7SJim Harris init_md(void) 575dfd44de7SJim Harris { 576dfd44de7SJim Harris struct spdk_reduce_vol_params params = {}; 577dfd44de7SJim Harris struct spdk_reduce_vol_params *persistent_params; 578dfd44de7SJim Harris struct spdk_reduce_backing_dev backing_dev = {}; 579d31f2be5SJim Harris struct spdk_uuid uuid; 580a03515deSJim Harris uint64_t *entry; 581dfd44de7SJim Harris 582dfd44de7SJim Harris params.chunk_size = 16 * 1024; 5833981ba69SJim Harris params.backing_io_unit_size = 512; 5845ae61d42SJim Harris params.logical_block_size = 512; 585dfd44de7SJim Harris 586212770dbSJim Harris backing_dev_init(&backing_dev, ¶ms, 512); 587dfd44de7SJim Harris 588dfd44de7SJim Harris g_vol = NULL; 5893213962eSJim Harris g_reduce_errno = -1; 590d31f2be5SJim Harris spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 5913213962eSJim Harris CU_ASSERT(g_reduce_errno == 0); 592dfd44de7SJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 593dfd44de7SJim Harris /* Confirm that reduce persisted the params to metadata. */ 594dfd44de7SJim Harris CU_ASSERT(memcmp(g_persistent_pm_buf, SPDK_REDUCE_SIGNATURE, 8) == 0); 595dfd44de7SJim Harris persistent_params = (struct spdk_reduce_vol_params *)(g_persistent_pm_buf + 8); 596dfd44de7SJim Harris CU_ASSERT(memcmp(persistent_params, ¶ms, sizeof(params)) == 0); 597a03515deSJim Harris /* Now confirm that contents of pm_file after the superblock have been initialized 598a03515deSJim Harris * to REDUCE_EMPTY_MAP_ENTRY. 599a03515deSJim Harris */ 600a03515deSJim Harris entry = (uint64_t *)(g_persistent_pm_buf + sizeof(struct spdk_reduce_vol_superblock)); 601a03515deSJim Harris while (entry != (uint64_t *)(g_persistent_pm_buf + g_vol->pm_file.size)) { 602a03515deSJim Harris CU_ASSERT(*entry == REDUCE_EMPTY_MAP_ENTRY); 603a03515deSJim Harris entry++; 604a03515deSJim Harris } 605dfd44de7SJim Harris 606d31f2be5SJim Harris /* Check that the pm file path was constructed correctly. It should be in 607d31f2be5SJim Harris * the form: 608d31f2be5SJim Harris * TEST_MD_PATH + "/" + <uuid string> 609d31f2be5SJim Harris */ 610d31f2be5SJim Harris CU_ASSERT(strncmp(&g_path[0], TEST_MD_PATH, strlen(TEST_MD_PATH)) == 0); 611d31f2be5SJim Harris CU_ASSERT(g_path[strlen(TEST_MD_PATH)] == '/'); 612d31f2be5SJim Harris CU_ASSERT(spdk_uuid_parse(&uuid, &g_path[strlen(TEST_MD_PATH) + 1]) == 0); 613d31f2be5SJim Harris CU_ASSERT(spdk_uuid_compare(&uuid, spdk_reduce_vol_get_uuid(g_vol)) == 0); 614d31f2be5SJim Harris 6153213962eSJim Harris g_reduce_errno = -1; 616dfd44de7SJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 6173213962eSJim Harris CU_ASSERT(g_reduce_errno == 0); 618c6323a8dSJim Harris CU_ASSERT(g_volatile_pm_buf == NULL); 619c6323a8dSJim Harris 620d31f2be5SJim Harris persistent_pm_buf_destroy(); 621b7623dd4SJim Harris backing_dev_destroy(&backing_dev); 622f28f8133SJim Harris } 623f28f8133SJim Harris 624b4f9dd1aSJim Harris static void 625212770dbSJim Harris _init_backing_dev(uint32_t backing_blocklen) 626b4f9dd1aSJim Harris { 627b4f9dd1aSJim Harris struct spdk_reduce_vol_params params = {}; 628b4f9dd1aSJim Harris struct spdk_reduce_vol_params *persistent_params; 629b4f9dd1aSJim Harris struct spdk_reduce_backing_dev backing_dev = {}; 630b4f9dd1aSJim Harris 631b4f9dd1aSJim Harris params.chunk_size = 16 * 1024; 632b4f9dd1aSJim Harris params.backing_io_unit_size = 512; 6335ae61d42SJim Harris params.logical_block_size = 512; 634b4f9dd1aSJim Harris spdk_uuid_generate(¶ms.uuid); 635b4f9dd1aSJim Harris 636212770dbSJim Harris backing_dev_init(&backing_dev, ¶ms, backing_blocklen); 637b4f9dd1aSJim Harris 638b4f9dd1aSJim Harris g_vol = NULL; 639c887a4f9SJim Harris memset(g_path, 0, sizeof(g_path)); 6403213962eSJim Harris g_reduce_errno = -1; 641d31f2be5SJim Harris spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 6423213962eSJim Harris CU_ASSERT(g_reduce_errno == 0); 643b4f9dd1aSJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 644c887a4f9SJim Harris CU_ASSERT(strncmp(TEST_MD_PATH, g_path, strlen(TEST_MD_PATH)) == 0); 645b4f9dd1aSJim Harris /* Confirm that libreduce persisted the params to the backing device. */ 646b4f9dd1aSJim Harris CU_ASSERT(memcmp(g_backing_dev_buf, SPDK_REDUCE_SIGNATURE, 8) == 0); 647b4f9dd1aSJim Harris persistent_params = (struct spdk_reduce_vol_params *)(g_backing_dev_buf + 8); 648b4f9dd1aSJim Harris CU_ASSERT(memcmp(persistent_params, ¶ms, sizeof(params)) == 0); 649cfc372c2SJim Harris /* Confirm that the path to the persistent memory metadata file was persisted to 650cfc372c2SJim Harris * the backing device. 651cfc372c2SJim Harris */ 652d31f2be5SJim Harris CU_ASSERT(strncmp(g_path, 653cfc372c2SJim Harris g_backing_dev_buf + REDUCE_BACKING_DEV_PATH_OFFSET, 654cfc372c2SJim Harris REDUCE_PATH_MAX) == 0); 655b4f9dd1aSJim Harris 6563213962eSJim Harris g_reduce_errno = -1; 657b4f9dd1aSJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 6583213962eSJim Harris CU_ASSERT(g_reduce_errno == 0); 659b4f9dd1aSJim Harris 660d31f2be5SJim Harris persistent_pm_buf_destroy(); 661b4f9dd1aSJim Harris backing_dev_destroy(&backing_dev); 662b4f9dd1aSJim Harris } 663b4f9dd1aSJim Harris 664eebdab61SJim Harris static void 665212770dbSJim Harris init_backing_dev(void) 666212770dbSJim Harris { 667212770dbSJim Harris _init_backing_dev(512); 668212770dbSJim Harris _init_backing_dev(4096); 669212770dbSJim Harris } 670212770dbSJim Harris 671212770dbSJim Harris static void 672212770dbSJim Harris _load(uint32_t backing_blocklen) 673eebdab61SJim Harris { 674eebdab61SJim Harris struct spdk_reduce_vol_params params = {}; 675eebdab61SJim Harris struct spdk_reduce_backing_dev backing_dev = {}; 676eebdab61SJim Harris char pmem_file_path[REDUCE_PATH_MAX]; 677eebdab61SJim Harris 678eebdab61SJim Harris params.chunk_size = 16 * 1024; 679eebdab61SJim Harris params.backing_io_unit_size = 512; 6805ae61d42SJim Harris params.logical_block_size = 512; 681eebdab61SJim Harris spdk_uuid_generate(¶ms.uuid); 682eebdab61SJim Harris 683212770dbSJim Harris backing_dev_init(&backing_dev, ¶ms, backing_blocklen); 684eebdab61SJim Harris 685eebdab61SJim Harris g_vol = NULL; 6863213962eSJim Harris g_reduce_errno = -1; 687eebdab61SJim Harris spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 6883213962eSJim Harris CU_ASSERT(g_reduce_errno == 0); 689eebdab61SJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 690c887a4f9SJim Harris CU_ASSERT(strncmp(TEST_MD_PATH, g_path, strlen(TEST_MD_PATH)) == 0); 691eebdab61SJim Harris memcpy(pmem_file_path, g_path, sizeof(pmem_file_path)); 692eebdab61SJim Harris 6933213962eSJim Harris g_reduce_errno = -1; 694eebdab61SJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 6953213962eSJim Harris CU_ASSERT(g_reduce_errno == 0); 696eebdab61SJim Harris 697eebdab61SJim Harris g_vol = NULL; 698c887a4f9SJim Harris memset(g_path, 0, sizeof(g_path)); 6993213962eSJim Harris g_reduce_errno = -1; 700eebdab61SJim Harris spdk_reduce_vol_load(&backing_dev, load_cb, NULL); 7013213962eSJim Harris CU_ASSERT(g_reduce_errno == 0); 702eebdab61SJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 703eebdab61SJim Harris CU_ASSERT(strncmp(g_path, pmem_file_path, sizeof(pmem_file_path)) == 0); 704922258a6SJim Harris CU_ASSERT(g_vol->params.vol_size == params.vol_size); 705922258a6SJim Harris CU_ASSERT(g_vol->params.chunk_size == params.chunk_size); 706922258a6SJim Harris CU_ASSERT(g_vol->params.backing_io_unit_size == params.backing_io_unit_size); 707eebdab61SJim Harris 7083213962eSJim Harris g_reduce_errno = -1; 709eebdab61SJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 7103213962eSJim Harris CU_ASSERT(g_reduce_errno == 0); 711eebdab61SJim Harris 712eebdab61SJim Harris persistent_pm_buf_destroy(); 713eebdab61SJim Harris backing_dev_destroy(&backing_dev); 714eebdab61SJim Harris } 715eebdab61SJim Harris 716212770dbSJim Harris static void 717212770dbSJim Harris load(void) 718212770dbSJim Harris { 719212770dbSJim Harris _load(512); 720212770dbSJim Harris _load(4096); 721212770dbSJim Harris } 722212770dbSJim Harris 72384f8b633SJim Harris static uint64_t 72484f8b633SJim Harris _vol_get_chunk_map_index(struct spdk_reduce_vol *vol, uint64_t offset) 72584f8b633SJim Harris { 72684f8b633SJim Harris uint64_t logical_map_index = offset / vol->logical_blocks_per_chunk; 72784f8b633SJim Harris 72884f8b633SJim Harris return vol->pm_logical_map[logical_map_index]; 72984f8b633SJim Harris } 73084f8b633SJim Harris 73184f8b633SJim Harris static void 73284f8b633SJim Harris write_cb(void *arg, int reduce_errno) 73384f8b633SJim Harris { 73484f8b633SJim Harris g_reduce_errno = reduce_errno; 73584f8b633SJim Harris } 73684f8b633SJim Harris 73784f8b633SJim Harris static void 738383b1173SJim Harris read_cb(void *arg, int reduce_errno) 739383b1173SJim Harris { 740383b1173SJim Harris g_reduce_errno = reduce_errno; 741383b1173SJim Harris } 742383b1173SJim Harris 743383b1173SJim Harris static void 744*412fced1SYalong Wang unmap_cb(void *arg, int reduce_errno) 745*412fced1SYalong Wang { 746*412fced1SYalong Wang g_reduce_errno = reduce_errno; 747*412fced1SYalong Wang } 748*412fced1SYalong Wang 749*412fced1SYalong Wang static void 750212770dbSJim Harris _write_maps(uint32_t backing_blocklen) 75184f8b633SJim Harris { 75284f8b633SJim Harris struct spdk_reduce_vol_params params = {}; 75384f8b633SJim Harris struct spdk_reduce_backing_dev backing_dev = {}; 75484f8b633SJim Harris struct iovec iov; 755cdd64c1cSJim Harris const int bufsize = 16 * 1024; /* chunk size */ 756cdd64c1cSJim Harris char buf[bufsize]; 757cdd64c1cSJim Harris uint32_t num_lbas, i; 75884f8b633SJim Harris uint64_t old_chunk0_map_index, new_chunk0_map_index; 7593c070c97SJim Harris struct spdk_reduce_chunk_map *old_chunk0_map, *new_chunk0_map; 76084f8b633SJim Harris 761cdd64c1cSJim Harris params.chunk_size = bufsize; 76284f8b633SJim Harris params.backing_io_unit_size = 4096; 76384f8b633SJim Harris params.logical_block_size = 512; 764cdd64c1cSJim Harris num_lbas = bufsize / params.logical_block_size; 76584f8b633SJim Harris spdk_uuid_generate(¶ms.uuid); 76684f8b633SJim Harris 767212770dbSJim Harris backing_dev_init(&backing_dev, ¶ms, backing_blocklen); 76884f8b633SJim Harris 76984f8b633SJim Harris g_vol = NULL; 77084f8b633SJim Harris g_reduce_errno = -1; 77184f8b633SJim Harris spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 77284f8b633SJim Harris CU_ASSERT(g_reduce_errno == 0); 77384f8b633SJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 77484f8b633SJim Harris 77584f8b633SJim Harris for (i = 0; i < g_vol->params.vol_size / g_vol->params.chunk_size; i++) { 77684f8b633SJim Harris CU_ASSERT(_vol_get_chunk_map_index(g_vol, i) == REDUCE_EMPTY_MAP_ENTRY); 77784f8b633SJim Harris } 77884f8b633SJim Harris 779cdd64c1cSJim Harris ut_build_data_buffer(buf, bufsize, 0x00, 1); 78084f8b633SJim Harris iov.iov_base = buf; 781cdd64c1cSJim Harris iov.iov_len = bufsize; 78284f8b633SJim Harris g_reduce_errno = -1; 783cdd64c1cSJim Harris spdk_reduce_vol_writev(g_vol, &iov, 1, 0, num_lbas, write_cb, NULL); 78484f8b633SJim Harris CU_ASSERT(g_reduce_errno == 0); 78584f8b633SJim Harris 78684f8b633SJim Harris old_chunk0_map_index = _vol_get_chunk_map_index(g_vol, 0); 78784f8b633SJim Harris CU_ASSERT(old_chunk0_map_index != REDUCE_EMPTY_MAP_ENTRY); 78884f8b633SJim Harris CU_ASSERT(spdk_bit_array_get(g_vol->allocated_chunk_maps, old_chunk0_map_index) == true); 78984f8b633SJim Harris 7903c070c97SJim Harris old_chunk0_map = _reduce_vol_get_chunk_map(g_vol, old_chunk0_map_index); 79184f8b633SJim Harris for (i = 0; i < g_vol->backing_io_units_per_chunk; i++) { 7923c070c97SJim Harris CU_ASSERT(old_chunk0_map->io_unit_index[i] != REDUCE_EMPTY_MAP_ENTRY); 7933c070c97SJim Harris CU_ASSERT(spdk_bit_array_get(g_vol->allocated_backing_io_units, 7943c070c97SJim Harris old_chunk0_map->io_unit_index[i]) == true); 79584f8b633SJim Harris } 79684f8b633SJim Harris 79784f8b633SJim Harris g_reduce_errno = -1; 798cdd64c1cSJim Harris spdk_reduce_vol_writev(g_vol, &iov, 1, 0, num_lbas, write_cb, NULL); 79984f8b633SJim Harris CU_ASSERT(g_reduce_errno == 0); 80084f8b633SJim Harris 80184f8b633SJim Harris new_chunk0_map_index = _vol_get_chunk_map_index(g_vol, 0); 80284f8b633SJim Harris CU_ASSERT(new_chunk0_map_index != REDUCE_EMPTY_MAP_ENTRY); 80384f8b633SJim Harris CU_ASSERT(new_chunk0_map_index != old_chunk0_map_index); 80484f8b633SJim Harris CU_ASSERT(spdk_bit_array_get(g_vol->allocated_chunk_maps, new_chunk0_map_index) == true); 80584f8b633SJim Harris CU_ASSERT(spdk_bit_array_get(g_vol->allocated_chunk_maps, old_chunk0_map_index) == false); 80684f8b633SJim Harris 80784f8b633SJim Harris for (i = 0; i < g_vol->backing_io_units_per_chunk; i++) { 8083c070c97SJim Harris CU_ASSERT(spdk_bit_array_get(g_vol->allocated_backing_io_units, 8093c070c97SJim Harris old_chunk0_map->io_unit_index[i]) == false); 81084f8b633SJim Harris } 81184f8b633SJim Harris 8123c070c97SJim Harris new_chunk0_map = _reduce_vol_get_chunk_map(g_vol, new_chunk0_map_index); 81384f8b633SJim Harris for (i = 0; i < g_vol->backing_io_units_per_chunk; i++) { 8143c070c97SJim Harris CU_ASSERT(new_chunk0_map->io_unit_index[i] != REDUCE_EMPTY_MAP_ENTRY); 8153c070c97SJim Harris CU_ASSERT(spdk_bit_array_get(g_vol->allocated_backing_io_units, 8163c070c97SJim Harris new_chunk0_map->io_unit_index[i]) == true); 81784f8b633SJim Harris } 81884f8b633SJim Harris 81984f8b633SJim Harris g_reduce_errno = -1; 82084f8b633SJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 82184f8b633SJim Harris CU_ASSERT(g_reduce_errno == 0); 82284f8b633SJim Harris 82384f8b633SJim Harris g_vol = NULL; 82484f8b633SJim Harris g_reduce_errno = -1; 82584f8b633SJim Harris spdk_reduce_vol_load(&backing_dev, load_cb, NULL); 82684f8b633SJim Harris CU_ASSERT(g_reduce_errno == 0); 82784f8b633SJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 82884f8b633SJim Harris CU_ASSERT(g_vol->params.vol_size == params.vol_size); 82984f8b633SJim Harris CU_ASSERT(g_vol->params.chunk_size == params.chunk_size); 83084f8b633SJim Harris CU_ASSERT(g_vol->params.backing_io_unit_size == params.backing_io_unit_size); 83184f8b633SJim Harris 83284f8b633SJim Harris g_reduce_errno = -1; 83384f8b633SJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 83484f8b633SJim Harris CU_ASSERT(g_reduce_errno == 0); 83584f8b633SJim Harris 83684f8b633SJim Harris persistent_pm_buf_destroy(); 83784f8b633SJim Harris backing_dev_destroy(&backing_dev); 83884f8b633SJim Harris } 83984f8b633SJim Harris 840212770dbSJim Harris static void 841212770dbSJim Harris write_maps(void) 842212770dbSJim Harris { 843212770dbSJim Harris _write_maps(512); 844212770dbSJim Harris _write_maps(4096); 845212770dbSJim Harris } 846383b1173SJim Harris 847383b1173SJim Harris static void 848212770dbSJim Harris _read_write(uint32_t backing_blocklen) 849383b1173SJim Harris { 850383b1173SJim Harris struct spdk_reduce_vol_params params = {}; 851383b1173SJim Harris struct spdk_reduce_backing_dev backing_dev = {}; 852383b1173SJim Harris struct iovec iov; 853383b1173SJim Harris char buf[16 * 1024]; /* chunk size */ 854383b1173SJim Harris char compare_buf[16 * 1024]; 855383b1173SJim Harris uint32_t i; 856383b1173SJim Harris 857383b1173SJim Harris params.chunk_size = 16 * 1024; 858383b1173SJim Harris params.backing_io_unit_size = 4096; 859383b1173SJim Harris params.logical_block_size = 512; 860383b1173SJim Harris spdk_uuid_generate(¶ms.uuid); 861383b1173SJim Harris 862212770dbSJim Harris backing_dev_init(&backing_dev, ¶ms, backing_blocklen); 863383b1173SJim Harris 864383b1173SJim Harris g_vol = NULL; 865383b1173SJim Harris g_reduce_errno = -1; 866383b1173SJim Harris spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 867383b1173SJim Harris CU_ASSERT(g_reduce_errno == 0); 868383b1173SJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 869383b1173SJim Harris 870383b1173SJim Harris /* Write 0xAA to 2 512-byte logical blocks, starting at LBA 2. */ 871383b1173SJim Harris memset(buf, 0xAA, 2 * params.logical_block_size); 872383b1173SJim Harris iov.iov_base = buf; 873383b1173SJim Harris iov.iov_len = 2 * params.logical_block_size; 874383b1173SJim Harris g_reduce_errno = -1; 875383b1173SJim Harris spdk_reduce_vol_writev(g_vol, &iov, 1, 2, 2, write_cb, NULL); 876383b1173SJim Harris CU_ASSERT(g_reduce_errno == 0); 877383b1173SJim Harris 878383b1173SJim Harris memset(compare_buf, 0xAA, sizeof(compare_buf)); 879383b1173SJim Harris for (i = 0; i < params.chunk_size / params.logical_block_size; i++) { 880383b1173SJim Harris memset(buf, 0xFF, params.logical_block_size); 881383b1173SJim Harris iov.iov_base = buf; 882383b1173SJim Harris iov.iov_len = params.logical_block_size; 883383b1173SJim Harris g_reduce_errno = -1; 884383b1173SJim Harris spdk_reduce_vol_readv(g_vol, &iov, 1, i, 1, read_cb, NULL); 885383b1173SJim Harris CU_ASSERT(g_reduce_errno == 0); 886383b1173SJim Harris 887383b1173SJim Harris switch (i) { 888383b1173SJim Harris case 2: 889383b1173SJim Harris case 3: 890383b1173SJim Harris CU_ASSERT(memcmp(buf, compare_buf, params.logical_block_size) == 0); 891383b1173SJim Harris break; 892383b1173SJim Harris default: 893383b1173SJim Harris CU_ASSERT(spdk_mem_all_zero(buf, params.logical_block_size)); 894383b1173SJim Harris break; 895383b1173SJim Harris } 896383b1173SJim Harris } 897383b1173SJim Harris 898383b1173SJim Harris g_reduce_errno = -1; 899383b1173SJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 900383b1173SJim Harris CU_ASSERT(g_reduce_errno == 0); 901383b1173SJim Harris 902cf467578Spaul luse /* Overwrite what we just wrote with 0xCC */ 903cf467578Spaul luse g_vol = NULL; 904cf467578Spaul luse g_reduce_errno = -1; 905cf467578Spaul luse spdk_reduce_vol_load(&backing_dev, load_cb, NULL); 906cf467578Spaul luse CU_ASSERT(g_reduce_errno == 0); 907cf467578Spaul luse SPDK_CU_ASSERT_FATAL(g_vol != NULL); 908cf467578Spaul luse CU_ASSERT(g_vol->params.vol_size == params.vol_size); 909cf467578Spaul luse CU_ASSERT(g_vol->params.chunk_size == params.chunk_size); 910cf467578Spaul luse CU_ASSERT(g_vol->params.backing_io_unit_size == params.backing_io_unit_size); 911cf467578Spaul luse 912cf467578Spaul luse memset(buf, 0xCC, 2 * params.logical_block_size); 913cf467578Spaul luse iov.iov_base = buf; 914cf467578Spaul luse iov.iov_len = 2 * params.logical_block_size; 915cf467578Spaul luse g_reduce_errno = -1; 916cf467578Spaul luse spdk_reduce_vol_writev(g_vol, &iov, 1, 2, 2, write_cb, NULL); 917cf467578Spaul luse CU_ASSERT(g_reduce_errno == 0); 918cf467578Spaul luse 919cf467578Spaul luse memset(compare_buf, 0xCC, sizeof(compare_buf)); 920cf467578Spaul luse for (i = 0; i < params.chunk_size / params.logical_block_size; i++) { 921cf467578Spaul luse memset(buf, 0xFF, params.logical_block_size); 922cf467578Spaul luse iov.iov_base = buf; 923cf467578Spaul luse iov.iov_len = params.logical_block_size; 924cf467578Spaul luse g_reduce_errno = -1; 925cf467578Spaul luse spdk_reduce_vol_readv(g_vol, &iov, 1, i, 1, read_cb, NULL); 926cf467578Spaul luse CU_ASSERT(g_reduce_errno == 0); 927cf467578Spaul luse 928cf467578Spaul luse switch (i) { 929cf467578Spaul luse case 2: 930cf467578Spaul luse case 3: 931cf467578Spaul luse CU_ASSERT(memcmp(buf, compare_buf, params.logical_block_size) == 0); 932cf467578Spaul luse break; 933cf467578Spaul luse default: 934cf467578Spaul luse CU_ASSERT(spdk_mem_all_zero(buf, params.logical_block_size)); 935cf467578Spaul luse break; 936cf467578Spaul luse } 937cf467578Spaul luse } 938cf467578Spaul luse 939cf467578Spaul luse g_reduce_errno = -1; 940cf467578Spaul luse spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 941cf467578Spaul luse CU_ASSERT(g_reduce_errno == 0); 942cf467578Spaul luse 943383b1173SJim Harris g_vol = NULL; 944383b1173SJim Harris g_reduce_errno = -1; 945383b1173SJim Harris spdk_reduce_vol_load(&backing_dev, load_cb, NULL); 946383b1173SJim Harris CU_ASSERT(g_reduce_errno == 0); 947383b1173SJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 948383b1173SJim Harris CU_ASSERT(g_vol->params.vol_size == params.vol_size); 949383b1173SJim Harris CU_ASSERT(g_vol->params.chunk_size == params.chunk_size); 950383b1173SJim Harris CU_ASSERT(g_vol->params.backing_io_unit_size == params.backing_io_unit_size); 951383b1173SJim Harris 952383b1173SJim Harris g_reduce_errno = -1; 95363ba545fSJim Harris 95463ba545fSJim Harris /* Write 0xBB to 2 512-byte logical blocks, starting at LBA 37. 95563ba545fSJim Harris * This is writing into the second chunk of the volume. This also 95663ba545fSJim Harris * enables implicitly checking that we reloaded the bit arrays 95763ba545fSJim Harris * correctly - making sure we don't use the first chunk map again 95863ba545fSJim Harris * for this new write - the first chunk map was already used by the 95963ba545fSJim Harris * write from before we unloaded and reloaded. 96063ba545fSJim Harris */ 96163ba545fSJim Harris memset(buf, 0xBB, 2 * params.logical_block_size); 96263ba545fSJim Harris iov.iov_base = buf; 96363ba545fSJim Harris iov.iov_len = 2 * params.logical_block_size; 96463ba545fSJim Harris g_reduce_errno = -1; 96563ba545fSJim Harris spdk_reduce_vol_writev(g_vol, &iov, 1, 37, 2, write_cb, NULL); 96663ba545fSJim Harris CU_ASSERT(g_reduce_errno == 0); 96763ba545fSJim Harris 96863ba545fSJim Harris for (i = 0; i < 2 * params.chunk_size / params.logical_block_size; i++) { 96963ba545fSJim Harris memset(buf, 0xFF, params.logical_block_size); 97063ba545fSJim Harris iov.iov_base = buf; 97163ba545fSJim Harris iov.iov_len = params.logical_block_size; 97263ba545fSJim Harris g_reduce_errno = -1; 97363ba545fSJim Harris spdk_reduce_vol_readv(g_vol, &iov, 1, i, 1, read_cb, NULL); 97463ba545fSJim Harris CU_ASSERT(g_reduce_errno == 0); 97563ba545fSJim Harris 97663ba545fSJim Harris switch (i) { 97763ba545fSJim Harris case 2: 97863ba545fSJim Harris case 3: 979cf467578Spaul luse memset(compare_buf, 0xCC, sizeof(compare_buf)); 98063ba545fSJim Harris CU_ASSERT(memcmp(buf, compare_buf, params.logical_block_size) == 0); 98163ba545fSJim Harris break; 98263ba545fSJim Harris case 37: 98363ba545fSJim Harris case 38: 98463ba545fSJim Harris memset(compare_buf, 0xBB, sizeof(compare_buf)); 98563ba545fSJim Harris CU_ASSERT(memcmp(buf, compare_buf, params.logical_block_size) == 0); 98663ba545fSJim Harris break; 98763ba545fSJim Harris default: 98863ba545fSJim Harris CU_ASSERT(spdk_mem_all_zero(buf, params.logical_block_size)); 98963ba545fSJim Harris break; 99063ba545fSJim Harris } 99163ba545fSJim Harris } 99263ba545fSJim Harris 99363ba545fSJim Harris g_reduce_errno = -1; 994383b1173SJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 995383b1173SJim Harris CU_ASSERT(g_reduce_errno == 0); 996383b1173SJim Harris 997383b1173SJim Harris persistent_pm_buf_destroy(); 998383b1173SJim Harris backing_dev_destroy(&backing_dev); 999383b1173SJim Harris } 1000383b1173SJim Harris 1001212770dbSJim Harris static void 1002212770dbSJim Harris read_write(void) 1003212770dbSJim Harris { 1004212770dbSJim Harris _read_write(512); 1005212770dbSJim Harris _read_write(4096); 1006212770dbSJim Harris } 1007212770dbSJim Harris 1008c0f38051SJim Harris static void 10094328a67eSSeth Howell _readv_writev(uint32_t backing_blocklen) 10104328a67eSSeth Howell { 10114328a67eSSeth Howell struct spdk_reduce_vol_params params = {}; 10124328a67eSSeth Howell struct spdk_reduce_backing_dev backing_dev = {}; 10134328a67eSSeth Howell struct iovec iov[REDUCE_MAX_IOVECS + 1]; 10144328a67eSSeth Howell 10154328a67eSSeth Howell params.chunk_size = 16 * 1024; 10164328a67eSSeth Howell params.backing_io_unit_size = 4096; 10174328a67eSSeth Howell params.logical_block_size = 512; 10184328a67eSSeth Howell spdk_uuid_generate(¶ms.uuid); 10194328a67eSSeth Howell 10204328a67eSSeth Howell backing_dev_init(&backing_dev, ¶ms, backing_blocklen); 10214328a67eSSeth Howell 10224328a67eSSeth Howell g_vol = NULL; 10234328a67eSSeth Howell g_reduce_errno = -1; 10244328a67eSSeth Howell spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 10254328a67eSSeth Howell CU_ASSERT(g_reduce_errno == 0); 10264328a67eSSeth Howell SPDK_CU_ASSERT_FATAL(g_vol != NULL); 10274328a67eSSeth Howell 10284328a67eSSeth Howell g_reduce_errno = -1; 10294328a67eSSeth Howell spdk_reduce_vol_writev(g_vol, iov, REDUCE_MAX_IOVECS + 1, 2, REDUCE_MAX_IOVECS + 1, write_cb, NULL); 10304328a67eSSeth Howell CU_ASSERT(g_reduce_errno == -EINVAL); 10314328a67eSSeth Howell 10324328a67eSSeth Howell g_reduce_errno = -1; 10334328a67eSSeth Howell spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 10344328a67eSSeth Howell CU_ASSERT(g_reduce_errno == 0); 10354328a67eSSeth Howell 10364328a67eSSeth Howell persistent_pm_buf_destroy(); 10374328a67eSSeth Howell backing_dev_destroy(&backing_dev); 10384328a67eSSeth Howell } 10394328a67eSSeth Howell 10404328a67eSSeth Howell static void 10414328a67eSSeth Howell readv_writev(void) 10424328a67eSSeth Howell { 10434328a67eSSeth Howell _readv_writev(512); 10444328a67eSSeth Howell _readv_writev(4096); 10454328a67eSSeth Howell } 10464328a67eSSeth Howell 1047*412fced1SYalong Wang /* 1.write offset 0KB, length 32KB, with 0xAA 1048*412fced1SYalong Wang * 2.unmap offset 8KB, length 24KB, fail with -EINVAL, verify 1049*412fced1SYalong Wang * 3.unmap offset 8KB, length 8KB 1050*412fced1SYalong Wang * 4.unmap offset 16KB, length 16KB 1051*412fced1SYalong Wang * 5.two fullchunk read verify 1052*412fced1SYalong Wang */ 1053*412fced1SYalong Wang static void 1054*412fced1SYalong Wang write_unmap_verify(void) 1055*412fced1SYalong Wang { 1056*412fced1SYalong Wang uint32_t backing_blocklen = 512; 1057*412fced1SYalong Wang uint64_t blocks_per_chunk; 1058*412fced1SYalong Wang 1059*412fced1SYalong Wang struct spdk_reduce_vol_params params = {}; 1060*412fced1SYalong Wang struct spdk_reduce_backing_dev backing_dev = {}; 1061*412fced1SYalong Wang struct iovec iov; 1062*412fced1SYalong Wang char buf[16 * 1024]; /* chunk size */ 1063*412fced1SYalong Wang char compare_buf[32 * 1024]; 1064*412fced1SYalong Wang 1065*412fced1SYalong Wang params.chunk_size = 16 * 1024; 1066*412fced1SYalong Wang params.backing_io_unit_size = 4096; 1067*412fced1SYalong Wang params.logical_block_size = 512; 1068*412fced1SYalong Wang spdk_uuid_generate(¶ms.uuid); 1069*412fced1SYalong Wang 1070*412fced1SYalong Wang backing_dev_init(&backing_dev, ¶ms, backing_blocklen); 1071*412fced1SYalong Wang 1072*412fced1SYalong Wang blocks_per_chunk = params.chunk_size / params.logical_block_size; 1073*412fced1SYalong Wang g_vol = NULL; 1074*412fced1SYalong Wang g_reduce_errno = -1; 1075*412fced1SYalong Wang spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 1076*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1077*412fced1SYalong Wang SPDK_CU_ASSERT_FATAL(g_vol != NULL); 1078*412fced1SYalong Wang 1079*412fced1SYalong Wang /* 1.write offset 0KB, length 32KB, with 0xAA */ 1080*412fced1SYalong Wang iov.iov_base = buf; 1081*412fced1SYalong Wang iov.iov_len = sizeof(buf); 1082*412fced1SYalong Wang memset(buf, 0xAA, sizeof(buf)); 1083*412fced1SYalong Wang g_reduce_errno = -1; 1084*412fced1SYalong Wang spdk_reduce_vol_writev(g_vol, &iov, 1, 0, blocks_per_chunk, write_cb, NULL); 1085*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1086*412fced1SYalong Wang g_reduce_errno = -1; 1087*412fced1SYalong Wang spdk_reduce_vol_writev(g_vol, &iov, 1, blocks_per_chunk, blocks_per_chunk, write_cb, NULL); 1088*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1089*412fced1SYalong Wang 1090*412fced1SYalong Wang memset(compare_buf, 0xAA, sizeof(compare_buf)); 1091*412fced1SYalong Wang 1092*412fced1SYalong Wang memset(buf, 0xFF, sizeof(buf)); 1093*412fced1SYalong Wang g_reduce_errno = -1; 1094*412fced1SYalong Wang spdk_reduce_vol_readv(g_vol, &iov, 1, 0, blocks_per_chunk, read_cb, NULL); 1095*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1096*412fced1SYalong Wang CU_ASSERT(memcmp(buf, compare_buf, sizeof(buf)) == 0); 1097*412fced1SYalong Wang 1098*412fced1SYalong Wang memset(buf, 0xFF, sizeof(buf)); 1099*412fced1SYalong Wang g_reduce_errno = -1; 1100*412fced1SYalong Wang spdk_reduce_vol_readv(g_vol, &iov, 1, blocks_per_chunk, blocks_per_chunk, read_cb, NULL); 1101*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1102*412fced1SYalong Wang CU_ASSERT(memcmp(buf, compare_buf + sizeof(buf), sizeof(buf)) == 0); 1103*412fced1SYalong Wang 1104*412fced1SYalong Wang /* 2.unmap offset 8KB, length 24KB, fail with -EINVAL */ 1105*412fced1SYalong Wang g_reduce_errno = 0; 1106*412fced1SYalong Wang spdk_reduce_vol_unmap(g_vol, 8 * 1024 / params.logical_block_size, 1107*412fced1SYalong Wang 24 * 1024 / params.logical_block_size, unmap_cb, NULL); 1108*412fced1SYalong Wang spdk_thread_poll(g_thread, 0, 0); 1109*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == -EINVAL); 1110*412fced1SYalong Wang 1111*412fced1SYalong Wang memset(buf, 0xFF, sizeof(buf)); 1112*412fced1SYalong Wang g_reduce_errno = -1; 1113*412fced1SYalong Wang spdk_reduce_vol_readv(g_vol, &iov, 1, 0, blocks_per_chunk, read_cb, NULL); 1114*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1115*412fced1SYalong Wang CU_ASSERT(memcmp(buf, compare_buf, sizeof(buf)) == 0); 1116*412fced1SYalong Wang 1117*412fced1SYalong Wang memset(buf, 0xFF, sizeof(buf)); 1118*412fced1SYalong Wang g_reduce_errno = -1; 1119*412fced1SYalong Wang spdk_reduce_vol_readv(g_vol, &iov, 1, blocks_per_chunk, blocks_per_chunk, read_cb, NULL); 1120*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1121*412fced1SYalong Wang CU_ASSERT(memcmp(buf, compare_buf + sizeof(buf), sizeof(buf)) == 0); 1122*412fced1SYalong Wang 1123*412fced1SYalong Wang /* 3.unmap offset 8KB, length 8KB */ 1124*412fced1SYalong Wang g_reduce_errno = -1; 1125*412fced1SYalong Wang spdk_reduce_vol_unmap(g_vol, 8 * 1024 / params.logical_block_size, 1126*412fced1SYalong Wang 8 * 1024 / params.logical_block_size, unmap_cb, NULL); 1127*412fced1SYalong Wang spdk_thread_poll(g_thread, 0, 0); 1128*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1129*412fced1SYalong Wang memset(compare_buf + 8 * 1024, 0x00, 8 * 1024); 1130*412fced1SYalong Wang 1131*412fced1SYalong Wang /* 4.unmap offset 16KB, length 16KB */ 1132*412fced1SYalong Wang g_reduce_errno = -1; 1133*412fced1SYalong Wang spdk_reduce_vol_unmap(g_vol, 16 * 1024 / params.logical_block_size, 1134*412fced1SYalong Wang 16 * 1024 / params.logical_block_size, unmap_cb, NULL); 1135*412fced1SYalong Wang spdk_thread_poll(g_thread, 0, 0); 1136*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1137*412fced1SYalong Wang memset(compare_buf + 16 * 1024, 0x00, 16 * 1024); 1138*412fced1SYalong Wang 1139*412fced1SYalong Wang /* 5.two fullchunk read verify */ 1140*412fced1SYalong Wang memset(buf, 0xFF, sizeof(buf)); 1141*412fced1SYalong Wang g_reduce_errno = -1; 1142*412fced1SYalong Wang spdk_reduce_vol_readv(g_vol, &iov, 1, 0, blocks_per_chunk, read_cb, NULL); 1143*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1144*412fced1SYalong Wang CU_ASSERT(memcmp(buf, compare_buf, sizeof(buf)) == 0); 1145*412fced1SYalong Wang 1146*412fced1SYalong Wang memset(buf, 0xFF, sizeof(buf)); 1147*412fced1SYalong Wang g_reduce_errno = -1; 1148*412fced1SYalong Wang spdk_reduce_vol_readv(g_vol, &iov, 1, blocks_per_chunk, blocks_per_chunk, read_cb, NULL); 1149*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1150*412fced1SYalong Wang CU_ASSERT(memcmp(buf, compare_buf + 16 * 1024, sizeof(buf)) == 0); 1151*412fced1SYalong Wang /* done */ 1152*412fced1SYalong Wang 1153*412fced1SYalong Wang g_reduce_errno = -1; 1154*412fced1SYalong Wang spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 1155*412fced1SYalong Wang CU_ASSERT(g_reduce_errno == 0); 1156*412fced1SYalong Wang 1157*412fced1SYalong Wang persistent_pm_buf_destroy(); 1158*412fced1SYalong Wang backing_dev_destroy(&backing_dev); 1159*412fced1SYalong Wang } 1160*412fced1SYalong Wang 11614328a67eSSeth Howell static void 1162c0f38051SJim Harris destroy_cb(void *ctx, int reduce_errno) 1163c0f38051SJim Harris { 1164c0f38051SJim Harris g_reduce_errno = reduce_errno; 1165c0f38051SJim Harris } 1166c0f38051SJim Harris 1167c0f38051SJim Harris static void 1168c0f38051SJim Harris destroy(void) 1169c0f38051SJim Harris { 1170c0f38051SJim Harris struct spdk_reduce_vol_params params = {}; 1171c0f38051SJim Harris struct spdk_reduce_backing_dev backing_dev = {}; 1172c0f38051SJim Harris 1173c0f38051SJim Harris params.chunk_size = 16 * 1024; 1174c0f38051SJim Harris params.backing_io_unit_size = 512; 1175c0f38051SJim Harris params.logical_block_size = 512; 1176c0f38051SJim Harris spdk_uuid_generate(¶ms.uuid); 1177c0f38051SJim Harris 1178c0f38051SJim Harris backing_dev_init(&backing_dev, ¶ms, 512); 1179c0f38051SJim Harris 1180c0f38051SJim Harris g_vol = NULL; 1181c0f38051SJim Harris g_reduce_errno = -1; 1182c0f38051SJim Harris spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 1183c0f38051SJim Harris CU_ASSERT(g_reduce_errno == 0); 1184c0f38051SJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 1185c0f38051SJim Harris 1186c0f38051SJim Harris g_reduce_errno = -1; 1187c0f38051SJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 1188c0f38051SJim Harris CU_ASSERT(g_reduce_errno == 0); 1189c0f38051SJim Harris 1190c0f38051SJim Harris g_vol = NULL; 1191c0f38051SJim Harris g_reduce_errno = -1; 1192c0f38051SJim Harris spdk_reduce_vol_load(&backing_dev, load_cb, NULL); 1193c0f38051SJim Harris CU_ASSERT(g_reduce_errno == 0); 1194c0f38051SJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 1195c0f38051SJim Harris 1196c0f38051SJim Harris g_reduce_errno = -1; 1197c0f38051SJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 1198c0f38051SJim Harris CU_ASSERT(g_reduce_errno == 0); 1199c0f38051SJim Harris 1200c0f38051SJim Harris g_reduce_errno = -1; 1201c0f38051SJim Harris MOCK_CLEAR(spdk_malloc); 1202c0f38051SJim Harris MOCK_CLEAR(spdk_zmalloc); 1203c0f38051SJim Harris spdk_reduce_vol_destroy(&backing_dev, destroy_cb, NULL); 1204c0f38051SJim Harris CU_ASSERT(g_reduce_errno == 0); 1205c0f38051SJim Harris 1206c0f38051SJim Harris g_reduce_errno = 0; 1207c0f38051SJim Harris spdk_reduce_vol_load(&backing_dev, load_cb, NULL); 1208c0f38051SJim Harris CU_ASSERT(g_reduce_errno == -EILSEQ); 1209c0f38051SJim Harris 1210c0f38051SJim Harris backing_dev_destroy(&backing_dev); 1211c0f38051SJim Harris } 1212c0f38051SJim Harris 121394d353eaSJim Harris /* This test primarily checks that the reduce unit test infrastructure for asynchronous 121494d353eaSJim Harris * backing device I/O operations is working correctly. 121594d353eaSJim Harris */ 121694d353eaSJim Harris static void 121794d353eaSJim Harris defer_bdev_io(void) 121894d353eaSJim Harris { 121994d353eaSJim Harris struct spdk_reduce_vol_params params = {}; 122094d353eaSJim Harris struct spdk_reduce_backing_dev backing_dev = {}; 122194d353eaSJim Harris const uint32_t logical_block_size = 512; 122294d353eaSJim Harris struct iovec iov; 122394d353eaSJim Harris char buf[logical_block_size]; 122494d353eaSJim Harris char compare_buf[logical_block_size]; 122594d353eaSJim Harris 122694d353eaSJim Harris params.chunk_size = 16 * 1024; 122794d353eaSJim Harris params.backing_io_unit_size = 4096; 122894d353eaSJim Harris params.logical_block_size = logical_block_size; 122994d353eaSJim Harris spdk_uuid_generate(¶ms.uuid); 123094d353eaSJim Harris 123194d353eaSJim Harris backing_dev_init(&backing_dev, ¶ms, 512); 123294d353eaSJim Harris 123394d353eaSJim Harris g_vol = NULL; 123494d353eaSJim Harris g_reduce_errno = -1; 123594d353eaSJim Harris spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 123694d353eaSJim Harris CU_ASSERT(g_reduce_errno == 0); 123794d353eaSJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 123894d353eaSJim Harris 123994d353eaSJim Harris /* Write 0xAA to 1 512-byte logical block. */ 124094d353eaSJim Harris memset(buf, 0xAA, params.logical_block_size); 124194d353eaSJim Harris iov.iov_base = buf; 124294d353eaSJim Harris iov.iov_len = params.logical_block_size; 124394d353eaSJim Harris g_reduce_errno = -100; 124494d353eaSJim Harris g_defer_bdev_io = true; 124594d353eaSJim Harris spdk_reduce_vol_writev(g_vol, &iov, 1, 0, 1, write_cb, NULL); 124694d353eaSJim Harris /* Callback should not have executed, so this should still equal -100. */ 124794d353eaSJim Harris CU_ASSERT(g_reduce_errno == -100); 124894d353eaSJim Harris CU_ASSERT(!TAILQ_EMPTY(&g_pending_bdev_io)); 12491679104eSJim Harris /* We wrote to just 512 bytes of one chunk which was previously unallocated. This 12501679104eSJim Harris * should result in 1 pending I/O since the rest of this chunk will be zeroes and 12511679104eSJim Harris * very compressible. 125294d353eaSJim Harris */ 12531679104eSJim Harris CU_ASSERT(g_pending_bdev_io_count == 1); 125494d353eaSJim Harris 125594d353eaSJim Harris backing_dev_io_execute(0); 125694d353eaSJim Harris CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io)); 125794d353eaSJim Harris CU_ASSERT(g_reduce_errno == 0); 125894d353eaSJim Harris 125994d353eaSJim Harris g_defer_bdev_io = false; 126094d353eaSJim Harris memset(compare_buf, 0xAA, sizeof(compare_buf)); 126194d353eaSJim Harris memset(buf, 0xFF, sizeof(buf)); 126294d353eaSJim Harris iov.iov_base = buf; 126394d353eaSJim Harris iov.iov_len = params.logical_block_size; 126494d353eaSJim Harris g_reduce_errno = -100; 126594d353eaSJim Harris spdk_reduce_vol_readv(g_vol, &iov, 1, 0, 1, read_cb, NULL); 126694d353eaSJim Harris CU_ASSERT(g_reduce_errno == 0); 126794d353eaSJim Harris CU_ASSERT(memcmp(buf, compare_buf, sizeof(buf)) == 0); 126894d353eaSJim Harris 126994d353eaSJim Harris g_reduce_errno = -1; 127094d353eaSJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 127194d353eaSJim Harris CU_ASSERT(g_reduce_errno == 0); 127294d353eaSJim Harris 127394d353eaSJim Harris persistent_pm_buf_destroy(); 127494d353eaSJim Harris backing_dev_destroy(&backing_dev); 127594d353eaSJim Harris } 127694d353eaSJim Harris 12774fb22601SJim Harris static void 12784fb22601SJim Harris overlapped(void) 12794fb22601SJim Harris { 12804fb22601SJim Harris struct spdk_reduce_vol_params params = {}; 12814fb22601SJim Harris struct spdk_reduce_backing_dev backing_dev = {}; 12824fb22601SJim Harris const uint32_t logical_block_size = 512; 12834fb22601SJim Harris struct iovec iov; 12844fb22601SJim Harris char buf[2 * logical_block_size]; 12854fb22601SJim Harris char compare_buf[2 * logical_block_size]; 12864fb22601SJim Harris 12874fb22601SJim Harris params.chunk_size = 16 * 1024; 12884fb22601SJim Harris params.backing_io_unit_size = 4096; 12894fb22601SJim Harris params.logical_block_size = logical_block_size; 12904fb22601SJim Harris spdk_uuid_generate(¶ms.uuid); 12914fb22601SJim Harris 12924fb22601SJim Harris backing_dev_init(&backing_dev, ¶ms, 512); 12934fb22601SJim Harris 12944fb22601SJim Harris g_vol = NULL; 12954fb22601SJim Harris g_reduce_errno = -1; 12964fb22601SJim Harris spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL); 12974fb22601SJim Harris CU_ASSERT(g_reduce_errno == 0); 12984fb22601SJim Harris SPDK_CU_ASSERT_FATAL(g_vol != NULL); 12994fb22601SJim Harris 13004fb22601SJim Harris /* Write 0xAA to 1 512-byte logical block. */ 13014fb22601SJim Harris memset(buf, 0xAA, logical_block_size); 13024fb22601SJim Harris iov.iov_base = buf; 13034fb22601SJim Harris iov.iov_len = logical_block_size; 13044fb22601SJim Harris g_reduce_errno = -100; 13054fb22601SJim Harris g_defer_bdev_io = true; 13064fb22601SJim Harris spdk_reduce_vol_writev(g_vol, &iov, 1, 0, 1, write_cb, NULL); 13074fb22601SJim Harris /* Callback should not have executed, so this should still equal -100. */ 13084fb22601SJim Harris CU_ASSERT(g_reduce_errno == -100); 13094fb22601SJim Harris CU_ASSERT(!TAILQ_EMPTY(&g_pending_bdev_io)); 13101679104eSJim Harris /* We wrote to just 512 bytes of one chunk which was previously unallocated. This 13111679104eSJim Harris * should result in 1 pending I/O since the rest of this chunk will be zeroes and 13121679104eSJim Harris * very compressible. 13131679104eSJim Harris */ 13141679104eSJim Harris CU_ASSERT(g_pending_bdev_io_count == 1); 13154fb22601SJim Harris 13164fb22601SJim Harris /* Now do an overlapped I/O to the same chunk. */ 13174fb22601SJim Harris spdk_reduce_vol_writev(g_vol, &iov, 1, 1, 1, write_cb, NULL); 13184fb22601SJim Harris /* Callback should not have executed, so this should still equal -100. */ 13194fb22601SJim Harris CU_ASSERT(g_reduce_errno == -100); 13204fb22601SJim Harris CU_ASSERT(!TAILQ_EMPTY(&g_pending_bdev_io)); 13214fb22601SJim Harris /* The second I/O overlaps with the first one. So we should only see pending bdev_io 13224fb22601SJim Harris * related to the first I/O here - the second one won't start until the first one is completed. 13234fb22601SJim Harris */ 13241679104eSJim Harris CU_ASSERT(g_pending_bdev_io_count == 1); 13254fb22601SJim Harris 13264fb22601SJim Harris backing_dev_io_execute(0); 13274fb22601SJim Harris CU_ASSERT(g_reduce_errno == 0); 13284fb22601SJim Harris 13294fb22601SJim Harris g_defer_bdev_io = false; 13304fb22601SJim Harris memset(compare_buf, 0xAA, sizeof(compare_buf)); 13314fb22601SJim Harris memset(buf, 0xFF, sizeof(buf)); 13324fb22601SJim Harris iov.iov_base = buf; 13334fb22601SJim Harris iov.iov_len = 2 * logical_block_size; 13344fb22601SJim Harris g_reduce_errno = -100; 13354fb22601SJim Harris spdk_reduce_vol_readv(g_vol, &iov, 1, 0, 2, read_cb, NULL); 13364fb22601SJim Harris CU_ASSERT(g_reduce_errno == 0); 13374fb22601SJim Harris CU_ASSERT(memcmp(buf, compare_buf, 2 * logical_block_size) == 0); 13384fb22601SJim Harris 13394fb22601SJim Harris g_reduce_errno = -1; 13404fb22601SJim Harris spdk_reduce_vol_unload(g_vol, unload_cb, NULL); 13414fb22601SJim Harris CU_ASSERT(g_reduce_errno == 0); 13424fb22601SJim Harris 13434fb22601SJim Harris persistent_pm_buf_destroy(); 13444fb22601SJim Harris backing_dev_destroy(&backing_dev); 13454fb22601SJim Harris } 13464fb22601SJim Harris 1347ac3077c3SJim Harris #define BUFSIZE 4096 1348ac3077c3SJim Harris 1349ac3077c3SJim Harris static void 1350ac3077c3SJim Harris compress_algorithm(void) 1351ac3077c3SJim Harris { 1352ac3077c3SJim Harris uint8_t original_data[BUFSIZE]; 1353ac3077c3SJim Harris uint8_t compressed_data[BUFSIZE]; 1354ac3077c3SJim Harris uint8_t decompressed_data[BUFSIZE]; 1355c1bab69cSJim Harris uint32_t compressed_len, decompressed_len; 1356ac3077c3SJim Harris int rc; 1357ac3077c3SJim Harris 1358c1bab69cSJim Harris ut_build_data_buffer(original_data, BUFSIZE, 0xAA, BUFSIZE); 1359ac3077c3SJim Harris compressed_len = sizeof(compressed_data); 1360ac3077c3SJim Harris rc = ut_compress(compressed_data, &compressed_len, original_data, UINT8_MAX); 1361ac3077c3SJim Harris CU_ASSERT(rc == 0); 1362ac3077c3SJim Harris CU_ASSERT(compressed_len == 2); 1363ac3077c3SJim Harris CU_ASSERT(compressed_data[0] == UINT8_MAX); 1364ac3077c3SJim Harris CU_ASSERT(compressed_data[1] == 0xAA); 1365ac3077c3SJim Harris 1366ac3077c3SJim Harris decompressed_len = sizeof(decompressed_data); 1367ac3077c3SJim Harris rc = ut_decompress(decompressed_data, &decompressed_len, compressed_data, compressed_len); 1368ac3077c3SJim Harris CU_ASSERT(rc == 0); 1369ac3077c3SJim Harris CU_ASSERT(decompressed_len == UINT8_MAX); 1370ac3077c3SJim Harris CU_ASSERT(memcmp(original_data, decompressed_data, decompressed_len) == 0); 1371ac3077c3SJim Harris 1372ac3077c3SJim Harris compressed_len = sizeof(compressed_data); 1373ac3077c3SJim Harris rc = ut_compress(compressed_data, &compressed_len, original_data, UINT8_MAX + 1); 1374ac3077c3SJim Harris CU_ASSERT(rc == 0); 1375ac3077c3SJim Harris CU_ASSERT(compressed_len == 4); 1376ac3077c3SJim Harris CU_ASSERT(compressed_data[0] == UINT8_MAX); 1377ac3077c3SJim Harris CU_ASSERT(compressed_data[1] == 0xAA); 1378ac3077c3SJim Harris CU_ASSERT(compressed_data[2] == 1); 1379ac3077c3SJim Harris CU_ASSERT(compressed_data[3] == 0xAA); 1380ac3077c3SJim Harris 1381ac3077c3SJim Harris decompressed_len = sizeof(decompressed_data); 1382ac3077c3SJim Harris rc = ut_decompress(decompressed_data, &decompressed_len, compressed_data, compressed_len); 1383ac3077c3SJim Harris CU_ASSERT(rc == 0); 1384ac3077c3SJim Harris CU_ASSERT(decompressed_len == UINT8_MAX + 1); 1385ac3077c3SJim Harris CU_ASSERT(memcmp(original_data, decompressed_data, decompressed_len) == 0); 1386ac3077c3SJim Harris 1387c1bab69cSJim Harris ut_build_data_buffer(original_data, BUFSIZE, 0x00, 1); 1388ac3077c3SJim Harris compressed_len = sizeof(compressed_data); 1389ac3077c3SJim Harris rc = ut_compress(compressed_data, &compressed_len, original_data, 2048); 1390ac3077c3SJim Harris CU_ASSERT(rc == 0); 1391ac3077c3SJim Harris CU_ASSERT(compressed_len == 4096); 1392ac3077c3SJim Harris CU_ASSERT(compressed_data[0] == 1); 1393ac3077c3SJim Harris CU_ASSERT(compressed_data[1] == 0); 1394ac3077c3SJim Harris CU_ASSERT(compressed_data[4094] == 1); 1395ac3077c3SJim Harris CU_ASSERT(compressed_data[4095] == 0xFF); 1396ac3077c3SJim Harris 1397ac3077c3SJim Harris decompressed_len = sizeof(decompressed_data); 1398ac3077c3SJim Harris rc = ut_decompress(decompressed_data, &decompressed_len, compressed_data, compressed_len); 1399ac3077c3SJim Harris CU_ASSERT(rc == 0); 1400ac3077c3SJim Harris CU_ASSERT(decompressed_len == 2048); 1401ac3077c3SJim Harris CU_ASSERT(memcmp(original_data, decompressed_data, decompressed_len) == 0); 1402ac3077c3SJim Harris 1403ac3077c3SJim Harris compressed_len = sizeof(compressed_data); 1404ac3077c3SJim Harris rc = ut_compress(compressed_data, &compressed_len, original_data, 2049); 1405ac3077c3SJim Harris CU_ASSERT(rc == -ENOSPC); 1406ac3077c3SJim Harris } 1407ac3077c3SJim Harris 140842f59f50SAlexey Marchuk static void 140942f59f50SAlexey Marchuk test_prepare_compress_chunk(void) 141042f59f50SAlexey Marchuk { 141142f59f50SAlexey Marchuk struct spdk_reduce_vol vol = {}; 141242f59f50SAlexey Marchuk struct spdk_reduce_backing_dev backing_dev = {}; 141342f59f50SAlexey Marchuk struct spdk_reduce_vol_request req = {}; 1414619b4dbaSAlexey Marchuk void *buf; 1415619b4dbaSAlexey Marchuk char *buffer_end, *aligned_user_buffer, *unaligned_user_buffer; 141642f59f50SAlexey Marchuk char decomp_buffer[16 * 1024] = {}; 141742f59f50SAlexey Marchuk char comp_buffer[16 * 1024] = {}; 141842f59f50SAlexey Marchuk struct iovec user_iov[2] = {}; 141942f59f50SAlexey Marchuk size_t user_buffer_iov_len = 8192; 142042f59f50SAlexey Marchuk size_t remainder_bytes; 142142f59f50SAlexey Marchuk size_t offset_bytes; 142242f59f50SAlexey Marchuk size_t memcmp_offset; 142342f59f50SAlexey Marchuk uint32_t i; 142442f59f50SAlexey Marchuk 142542f59f50SAlexey Marchuk vol.params.chunk_size = 16 * 1024; 142642f59f50SAlexey Marchuk vol.params.backing_io_unit_size = 4096; 142742f59f50SAlexey Marchuk vol.params.logical_block_size = 512; 142842f59f50SAlexey Marchuk backing_dev_init(&backing_dev, &vol.params, 512); 142942f59f50SAlexey Marchuk vol.backing_dev = &backing_dev; 143042f59f50SAlexey Marchuk vol.logical_blocks_per_chunk = vol.params.chunk_size / vol.params.logical_block_size; 143142f59f50SAlexey Marchuk 1432619b4dbaSAlexey Marchuk /* Allocate 1 extra byte to test a case when buffer crosses huge page boundary */ 1433619b4dbaSAlexey Marchuk SPDK_CU_ASSERT_FATAL(posix_memalign(&buf, VALUE_2MB, VALUE_2MB + 1) == 0); 1434619b4dbaSAlexey Marchuk buffer_end = (char *)buf + VALUE_2MB + 1; 1435619b4dbaSAlexey Marchuk aligned_user_buffer = (char *)buf; 1436619b4dbaSAlexey Marchuk memset(aligned_user_buffer, 0xc, vol.params.chunk_size); 1437619b4dbaSAlexey Marchuk unaligned_user_buffer = buffer_end - vol.params.chunk_size; 1438619b4dbaSAlexey Marchuk memset(unaligned_user_buffer, 0xc, vol.params.chunk_size); 1439619b4dbaSAlexey Marchuk 144042f59f50SAlexey Marchuk req.vol = &vol; 144142f59f50SAlexey Marchuk req.decomp_buf = decomp_buffer; 144242f59f50SAlexey Marchuk req.comp_buf = comp_buffer; 144342f59f50SAlexey Marchuk req.iov = user_iov; 144442f59f50SAlexey Marchuk req.iovcnt = 2; 144542f59f50SAlexey Marchuk req.offset = 0; 144642f59f50SAlexey Marchuk 144742f59f50SAlexey Marchuk /* Part 1 - backing dev supports sgl_in */ 144842f59f50SAlexey Marchuk /* Test 1 - user's buffers length equals to chunk_size */ 144942f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 1450619b4dbaSAlexey Marchuk req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len; 145142f59f50SAlexey Marchuk req.iov[i].iov_len = user_buffer_iov_len; 145242f59f50SAlexey Marchuk } 145342f59f50SAlexey Marchuk 145442f59f50SAlexey Marchuk _prepare_compress_chunk(&req, false); 145542f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 2); 145642f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 145742f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base); 145842f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len); 145942f59f50SAlexey Marchuk } 146042f59f50SAlexey Marchuk 146142f59f50SAlexey Marchuk _prepare_compress_chunk(&req, true); 146242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 2); 146342f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 146442f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base); 146542f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len); 146642f59f50SAlexey Marchuk } 146742f59f50SAlexey Marchuk 146842f59f50SAlexey Marchuk /* Test 2 - user's buffer less than chunk_size, without offset */ 146942f59f50SAlexey Marchuk user_buffer_iov_len = 4096; 147042f59f50SAlexey Marchuk remainder_bytes = vol.params.chunk_size - user_buffer_iov_len * 2; 147142f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 1472619b4dbaSAlexey Marchuk req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len; 147342f59f50SAlexey Marchuk req.iov[i].iov_len = user_buffer_iov_len; 147442f59f50SAlexey Marchuk } 147542f59f50SAlexey Marchuk 147642f59f50SAlexey Marchuk _prepare_compress_chunk(&req, false); 147742f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 3); 147842f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 147942f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base); 148042f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len); 148142f59f50SAlexey Marchuk } 148242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_base == req.decomp_buf + user_buffer_iov_len * 2); 148342f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_len == remainder_bytes); 148442f59f50SAlexey Marchuk 148542f59f50SAlexey Marchuk _prepare_compress_chunk(&req, true); 148642f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 3); 148742f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 148842f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base); 148942f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len); 149042f59f50SAlexey Marchuk } 149142f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_base == g_zero_buf + user_buffer_iov_len * 2); 149242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_len == remainder_bytes); 149342f59f50SAlexey Marchuk 149442f59f50SAlexey Marchuk /* Test 3 - user's buffer less than chunk_size, non zero offset */ 149542f59f50SAlexey Marchuk user_buffer_iov_len = 4096; 149642f59f50SAlexey Marchuk req.offset = 3; 149742f59f50SAlexey Marchuk offset_bytes = req.offset * vol.params.logical_block_size; 149842f59f50SAlexey Marchuk remainder_bytes = vol.params.chunk_size - offset_bytes - user_buffer_iov_len * 2; 149942f59f50SAlexey Marchuk 150042f59f50SAlexey Marchuk _prepare_compress_chunk(&req, false); 150142f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 4); 150242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 150342f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == offset_bytes); 150442f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 150542f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i + 1].iov_base == req.iov[i].iov_base); 150642f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i + 1].iov_len == req.iov[i].iov_len); 150742f59f50SAlexey Marchuk } 150842f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[3].iov_base == req.decomp_buf + offset_bytes + user_buffer_iov_len * 2); 150942f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[3].iov_len == remainder_bytes); 151042f59f50SAlexey Marchuk 151142f59f50SAlexey Marchuk _prepare_compress_chunk(&req, true); 151242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 4); 151342f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == g_zero_buf); 151442f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == offset_bytes); 151542f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 151642f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i + 1].iov_base == req.iov[i].iov_base); 151742f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i + 1].iov_len == req.iov[i].iov_len); 151842f59f50SAlexey Marchuk } 151942f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[3].iov_base == g_zero_buf + offset_bytes + user_buffer_iov_len * 2); 152042f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[3].iov_len == remainder_bytes); 152142f59f50SAlexey Marchuk 152242f59f50SAlexey Marchuk /* Part 2 - backing dev doesn't support sgl_in */ 152342f59f50SAlexey Marchuk /* Test 1 - user's buffers length equals to chunk_size 152442f59f50SAlexey Marchuk * user's buffers are copied */ 152542f59f50SAlexey Marchuk vol.backing_dev->sgl_in = false; 152642f59f50SAlexey Marchuk req.offset = 0; 152742f59f50SAlexey Marchuk user_buffer_iov_len = 8192; 152842f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 1529619b4dbaSAlexey Marchuk req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len; 153042f59f50SAlexey Marchuk req.iov[i].iov_len = user_buffer_iov_len; 153142f59f50SAlexey Marchuk memset(req.iov[i].iov_base, 0xb + i, req.iov[i].iov_len); 153242f59f50SAlexey Marchuk } 153342f59f50SAlexey Marchuk 153442f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 153542f59f50SAlexey Marchuk 153642f59f50SAlexey Marchuk _prepare_compress_chunk(&req, false); 153742f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 153842f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 153942f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 154042f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base, req.iov[0].iov_base, req.iov[0].iov_len) == 0); 154142f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + req.iov[0].iov_len, req.iov[1].iov_base, 154242f59f50SAlexey Marchuk req.iov[1].iov_len) == 0); 154342f59f50SAlexey Marchuk 154442f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 154542f59f50SAlexey Marchuk 154642f59f50SAlexey Marchuk _prepare_compress_chunk(&req, true); 154742f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 154842f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 154942f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 155042f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base, req.iov[0].iov_base, req.iov[0].iov_len) == 0); 155142f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + req.iov[0].iov_len, req.iov[1].iov_base, 155242f59f50SAlexey Marchuk req.iov[1].iov_len) == 0); 155342f59f50SAlexey Marchuk 1554619b4dbaSAlexey Marchuk /* Test 2 - single user's buffer length equals to chunk_size, buffer is not aligned 1555619b4dbaSAlexey Marchuk * User's buffer is copied */ 1556619b4dbaSAlexey Marchuk req.iov[0].iov_base = unaligned_user_buffer; 1557619b4dbaSAlexey Marchuk req.iov[0].iov_len = vol.params.chunk_size; 1558619b4dbaSAlexey Marchuk req.iovcnt = 1; 1559619b4dbaSAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 1560619b4dbaSAlexey Marchuk 1561619b4dbaSAlexey Marchuk _prepare_compress_chunk(&req, false); 1562619b4dbaSAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 1563619b4dbaSAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 1564619b4dbaSAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 1565619b4dbaSAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base, req.iov[0].iov_base, 1566619b4dbaSAlexey Marchuk req.iov[0].iov_len) == 0); 1567619b4dbaSAlexey Marchuk 1568619b4dbaSAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 1569619b4dbaSAlexey Marchuk 1570619b4dbaSAlexey Marchuk _prepare_compress_chunk(&req, true); 1571619b4dbaSAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 1572619b4dbaSAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 1573619b4dbaSAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 1574619b4dbaSAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base, req.iov[0].iov_base, 1575619b4dbaSAlexey Marchuk req.iov[0].iov_len) == 0); 1576619b4dbaSAlexey Marchuk 1577619b4dbaSAlexey Marchuk /* Test 3 - single user's buffer length equals to chunk_size 157842f59f50SAlexey Marchuk * User's buffer is not copied */ 1579619b4dbaSAlexey Marchuk req.iov[0].iov_base = aligned_user_buffer; 158042f59f50SAlexey Marchuk req.iov[0].iov_len = vol.params.chunk_size; 158142f59f50SAlexey Marchuk req.iovcnt = 1; 158242f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 158342f59f50SAlexey Marchuk 158442f59f50SAlexey Marchuk _prepare_compress_chunk(&req, false); 158542f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 158642f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.iov[0].iov_base); 158742f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 158842f59f50SAlexey Marchuk 158942f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 159042f59f50SAlexey Marchuk 159142f59f50SAlexey Marchuk _prepare_compress_chunk(&req, true); 159242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 159342f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.iov[0].iov_base); 159442f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 159542f59f50SAlexey Marchuk 1596619b4dbaSAlexey Marchuk /* Test 4 - user's buffer less than chunk_size, without offset 159742f59f50SAlexey Marchuk * User's buffers are copied */ 159842f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 159942f59f50SAlexey Marchuk user_buffer_iov_len = 4096; 160042f59f50SAlexey Marchuk req.iovcnt = 2; 160142f59f50SAlexey Marchuk remainder_bytes = vol.params.chunk_size - user_buffer_iov_len * 2; 160242f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 1603619b4dbaSAlexey Marchuk req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len; 160442f59f50SAlexey Marchuk req.iov[i].iov_len = user_buffer_iov_len; 160542f59f50SAlexey Marchuk } 160642f59f50SAlexey Marchuk 160742f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 160842f59f50SAlexey Marchuk 160942f59f50SAlexey Marchuk _prepare_compress_chunk(&req, false); 161042f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 161142f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 161242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 161342f59f50SAlexey Marchuk memcmp_offset = 0; 161442f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[0].iov_base, 161542f59f50SAlexey Marchuk req.iov[0].iov_len) == 0); 161642f59f50SAlexey Marchuk memcmp_offset += req.iov[0].iov_len; 161742f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[1].iov_base, 161842f59f50SAlexey Marchuk req.iov[1].iov_len) == 0); 161942f59f50SAlexey Marchuk memcmp_offset += req.iov[0].iov_len; 162042f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.decomp_buf + memcmp_offset, 162142f59f50SAlexey Marchuk remainder_bytes) == 0); 162242f59f50SAlexey Marchuk 162342f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 162442f59f50SAlexey Marchuk 162542f59f50SAlexey Marchuk _prepare_compress_chunk(&req, true); 162642f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 162742f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 162842f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 162942f59f50SAlexey Marchuk memcmp_offset = 0; 163042f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[0].iov_base, 163142f59f50SAlexey Marchuk req.iov[0].iov_len) == 0); 163242f59f50SAlexey Marchuk memcmp_offset += req.iov[0].iov_len; 163342f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[1].iov_base, 163442f59f50SAlexey Marchuk req.iov[1].iov_len) == 0); 163542f59f50SAlexey Marchuk memcmp_offset += req.iov[0].iov_len; 163642f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, g_zero_buf + memcmp_offset, 163742f59f50SAlexey Marchuk remainder_bytes) == 0); 163842f59f50SAlexey Marchuk 1639619b4dbaSAlexey Marchuk /* Test 5 - user's buffer less than chunk_size, non zero offset 164042f59f50SAlexey Marchuk * user's buffers are copied */ 164142f59f50SAlexey Marchuk req.offset = 3; 164242f59f50SAlexey Marchuk offset_bytes = req.offset * vol.params.logical_block_size; 164342f59f50SAlexey Marchuk remainder_bytes = vol.params.chunk_size - offset_bytes - user_buffer_iov_len * 2; 164442f59f50SAlexey Marchuk 164542f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 164642f59f50SAlexey Marchuk 164742f59f50SAlexey Marchuk _prepare_compress_chunk(&req, false); 164842f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 164942f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 165042f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 165142f59f50SAlexey Marchuk memcmp_offset = 0; 165242f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.decomp_buf, offset_bytes) == 0); 165342f59f50SAlexey Marchuk memcmp_offset += offset_bytes; 165442f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[0].iov_base, 165542f59f50SAlexey Marchuk req.iov[0].iov_len) == 0); 165642f59f50SAlexey Marchuk memcmp_offset += req.iov[0].iov_len; 165742f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[1].iov_base, 165842f59f50SAlexey Marchuk req.iov[1].iov_len) == 0); 165942f59f50SAlexey Marchuk memcmp_offset += req.iov[1].iov_len; 166042f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.decomp_buf + memcmp_offset, 166142f59f50SAlexey Marchuk remainder_bytes) == 0); 166242f59f50SAlexey Marchuk 166342f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 166442f59f50SAlexey Marchuk 166542f59f50SAlexey Marchuk _prepare_compress_chunk(&req, true); 166642f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 166742f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 166842f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 166942f59f50SAlexey Marchuk memcmp_offset = 0; 167042f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, g_zero_buf, offset_bytes) == 0); 167142f59f50SAlexey Marchuk memcmp_offset += offset_bytes; 167242f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[0].iov_base, 167342f59f50SAlexey Marchuk req.iov[0].iov_len) == 0); 167442f59f50SAlexey Marchuk memcmp_offset += req.iov[0].iov_len; 167542f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, req.iov[1].iov_base, 167642f59f50SAlexey Marchuk req.iov[1].iov_len) == 0); 167742f59f50SAlexey Marchuk memcmp_offset += req.iov[1].iov_len; 167842f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + memcmp_offset, g_zero_buf + memcmp_offset, 167942f59f50SAlexey Marchuk remainder_bytes) == 0); 16807e55f977Spaul luse backing_dev_destroy(&backing_dev); 1681619b4dbaSAlexey Marchuk free(buf); 168242f59f50SAlexey Marchuk } 168342f59f50SAlexey Marchuk 16848dd1cd21SBen Walker static void 16858dd1cd21SBen Walker _reduce_vol_op_complete(void *ctx, int reduce_errno) 168642f59f50SAlexey Marchuk { 168742f59f50SAlexey Marchuk g_reduce_errno = reduce_errno; 168842f59f50SAlexey Marchuk } 168942f59f50SAlexey Marchuk 169042f59f50SAlexey Marchuk static void 169142f59f50SAlexey Marchuk dummy_backing_dev_decompress(struct spdk_reduce_backing_dev *backing_dev, 169242f59f50SAlexey Marchuk struct iovec *src_iov, int src_iovcnt, 169342f59f50SAlexey Marchuk struct iovec *dst_iov, int dst_iovcnt, 169442f59f50SAlexey Marchuk struct spdk_reduce_vol_cb_args *args) 169542f59f50SAlexey Marchuk { 1696bb5083a8Spaul luse args->output_size = g_decompressed_len; 1697bb5083a8Spaul luse args->cb_fn(args->cb_arg, 0); 169842f59f50SAlexey Marchuk } 16998dd1cd21SBen Walker static void 17008dd1cd21SBen Walker test_reduce_decompress_chunk(void) 170142f59f50SAlexey Marchuk { 170242f59f50SAlexey Marchuk struct spdk_reduce_vol vol = {}; 170342f59f50SAlexey Marchuk struct spdk_reduce_backing_dev backing_dev = {}; 170442f59f50SAlexey Marchuk struct spdk_reduce_vol_request req = {}; 1705619b4dbaSAlexey Marchuk void *buf; 1706619b4dbaSAlexey Marchuk char *buffer_end, *aligned_user_buffer, *unaligned_user_buffer; 170742f59f50SAlexey Marchuk char decomp_buffer[16 * 1024] = {}; 170842f59f50SAlexey Marchuk char comp_buffer[16 * 1024] = {}; 170942f59f50SAlexey Marchuk struct iovec user_iov[2] = {}; 171042f59f50SAlexey Marchuk struct iovec comp_buf_iov = {}; 171142f59f50SAlexey Marchuk struct spdk_reduce_chunk_map chunk = {}; 171242f59f50SAlexey Marchuk size_t user_buffer_iov_len = 8192; 171342f59f50SAlexey Marchuk size_t remainder_bytes; 171442f59f50SAlexey Marchuk size_t offset_bytes; 171542f59f50SAlexey Marchuk uint32_t i; 171642f59f50SAlexey Marchuk 171742f59f50SAlexey Marchuk vol.params.chunk_size = 16 * 1024; 171842f59f50SAlexey Marchuk vol.params.backing_io_unit_size = 4096; 171942f59f50SAlexey Marchuk vol.params.logical_block_size = 512; 172042f59f50SAlexey Marchuk backing_dev_init(&backing_dev, &vol.params, 512); 172142f59f50SAlexey Marchuk backing_dev.decompress = dummy_backing_dev_decompress; 172242f59f50SAlexey Marchuk vol.backing_dev = &backing_dev; 172342f59f50SAlexey Marchuk vol.logical_blocks_per_chunk = vol.params.chunk_size / vol.params.logical_block_size; 17246881fb40SYalong Wang RB_INIT(&vol.executing_requests); 172542f59f50SAlexey Marchuk TAILQ_INIT(&vol.queued_requests); 172642f59f50SAlexey Marchuk TAILQ_INIT(&vol.free_requests); 172742f59f50SAlexey Marchuk 1728619b4dbaSAlexey Marchuk /* Allocate 1 extra byte to test a case when buffer crosses huge page boundary */ 1729619b4dbaSAlexey Marchuk SPDK_CU_ASSERT_FATAL(posix_memalign(&buf, VALUE_2MB, VALUE_2MB + 1) == 0); 1730619b4dbaSAlexey Marchuk buffer_end = (char *)buf + VALUE_2MB + 1; 1731619b4dbaSAlexey Marchuk aligned_user_buffer = (char *)buf; 1732619b4dbaSAlexey Marchuk unaligned_user_buffer = buffer_end - vol.params.chunk_size; 1733619b4dbaSAlexey Marchuk 173442f59f50SAlexey Marchuk chunk.compressed_size = user_buffer_iov_len / 2; 173542f59f50SAlexey Marchuk req.chunk = &chunk; 173642f59f50SAlexey Marchuk req.vol = &vol; 173742f59f50SAlexey Marchuk req.decomp_buf = decomp_buffer; 173842f59f50SAlexey Marchuk req.comp_buf = comp_buffer; 173942f59f50SAlexey Marchuk req.comp_buf_iov = &comp_buf_iov; 174042f59f50SAlexey Marchuk req.iov = user_iov; 174142f59f50SAlexey Marchuk req.iovcnt = 2; 174242f59f50SAlexey Marchuk req.offset = 0; 174342f59f50SAlexey Marchuk req.cb_fn = _reduce_vol_op_complete; 174442f59f50SAlexey Marchuk 174542f59f50SAlexey Marchuk /* Part 1 - backing dev supports sgl_out */ 174642f59f50SAlexey Marchuk /* Test 1 - user's buffers length equals to chunk_size */ 174742f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 1748619b4dbaSAlexey Marchuk req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len; 174942f59f50SAlexey Marchuk req.iov[i].iov_len = user_buffer_iov_len; 175042f59f50SAlexey Marchuk memset(req.iov[i].iov_base, 0, req.iov[i].iov_len); 175142f59f50SAlexey Marchuk } 17526881fb40SYalong Wang RB_INSERT(executing_req_tree, &vol.executing_requests, &req); 175342f59f50SAlexey Marchuk g_reduce_errno = -1; 175442f59f50SAlexey Marchuk g_decompressed_len = vol.params.chunk_size; 175542f59f50SAlexey Marchuk 175642f59f50SAlexey Marchuk _reduce_vol_decompress_chunk(&req, _read_decompress_done); 175742f59f50SAlexey Marchuk CU_ASSERT(g_reduce_errno == 0); 175842f59f50SAlexey Marchuk CU_ASSERT(req.copy_after_decompress == false); 175942f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 2); 176042f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 176142f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base); 176242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len); 176342f59f50SAlexey Marchuk } 17646881fb40SYalong Wang CU_ASSERT(RB_EMPTY(&vol.executing_requests)); 176542f59f50SAlexey Marchuk CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req); 176642f59f50SAlexey Marchuk 176742f59f50SAlexey Marchuk /* Test 2 - user's buffer less than chunk_size, without offset */ 17686881fb40SYalong Wang RB_INSERT(executing_req_tree, &vol.executing_requests, &req); 176942f59f50SAlexey Marchuk g_reduce_errno = -1; 177042f59f50SAlexey Marchuk user_buffer_iov_len = 4096; 177142f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 1772619b4dbaSAlexey Marchuk req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len; 177342f59f50SAlexey Marchuk req.iov[i].iov_len = user_buffer_iov_len; 177442f59f50SAlexey Marchuk memset(req.iov[i].iov_base, 0, req.iov[i].iov_len); 177542f59f50SAlexey Marchuk } 177642f59f50SAlexey Marchuk remainder_bytes = vol.params.chunk_size - user_buffer_iov_len * 2; 177742f59f50SAlexey Marchuk 177842f59f50SAlexey Marchuk _reduce_vol_decompress_chunk(&req, _read_decompress_done); 177942f59f50SAlexey Marchuk CU_ASSERT(g_reduce_errno == 0); 178042f59f50SAlexey Marchuk CU_ASSERT(req.copy_after_decompress == false); 178142f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 3); 178242f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 178342f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_base == req.iov[i].iov_base); 178442f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_len == req.iov[i].iov_len); 178542f59f50SAlexey Marchuk } 178642f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_base == req.decomp_buf + user_buffer_iov_len * 2); 178742f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i].iov_len == remainder_bytes); 17886881fb40SYalong Wang CU_ASSERT(RB_EMPTY(&vol.executing_requests)); 178942f59f50SAlexey Marchuk CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req); 179042f59f50SAlexey Marchuk 179142f59f50SAlexey Marchuk /* Test 3 - user's buffer less than chunk_size, non zero offset */ 179242f59f50SAlexey Marchuk req.offset = 3; 179342f59f50SAlexey Marchuk offset_bytes = req.offset * vol.params.logical_block_size; 179442f59f50SAlexey Marchuk remainder_bytes = vol.params.chunk_size - offset_bytes - user_buffer_iov_len * 2; 17956881fb40SYalong Wang RB_INSERT(executing_req_tree, &vol.executing_requests, &req); 179642f59f50SAlexey Marchuk g_reduce_errno = -1; 179742f59f50SAlexey Marchuk 179842f59f50SAlexey Marchuk _reduce_vol_decompress_chunk(&req, _read_decompress_done); 179942f59f50SAlexey Marchuk CU_ASSERT(g_reduce_errno == 0); 180042f59f50SAlexey Marchuk CU_ASSERT(req.copy_after_decompress == false); 180142f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 4); 180242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 180342f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == offset_bytes); 180442f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 180542f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i + 1].iov_base == req.iov[i].iov_base); 180642f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[i + 1].iov_len == req.iov[i].iov_len); 180742f59f50SAlexey Marchuk } 180842f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[3].iov_base == req.decomp_buf + offset_bytes + user_buffer_iov_len * 2); 180942f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[3].iov_len == remainder_bytes); 18106881fb40SYalong Wang CU_ASSERT(RB_EMPTY(&vol.executing_requests)); 181142f59f50SAlexey Marchuk CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req); 181242f59f50SAlexey Marchuk 181342f59f50SAlexey Marchuk /* Part 2 - backing dev doesn't support sgl_out */ 181442f59f50SAlexey Marchuk /* Test 1 - user's buffers length equals to chunk_size 181542f59f50SAlexey Marchuk * user's buffers are copied */ 181642f59f50SAlexey Marchuk vol.backing_dev->sgl_out = false; 181742f59f50SAlexey Marchuk req.offset = 0; 181842f59f50SAlexey Marchuk user_buffer_iov_len = 8192; 181942f59f50SAlexey Marchuk 182042f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 182142f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 1822619b4dbaSAlexey Marchuk req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len; 182342f59f50SAlexey Marchuk req.iov[i].iov_len = user_buffer_iov_len; 182442f59f50SAlexey Marchuk memset(req.iov[i].iov_base, 0xb + i, req.iov[i].iov_len); 182542f59f50SAlexey Marchuk } 18266881fb40SYalong Wang RB_INSERT(executing_req_tree, &vol.executing_requests, &req); 182742f59f50SAlexey Marchuk g_reduce_errno = -1; 182842f59f50SAlexey Marchuk 182942f59f50SAlexey Marchuk _reduce_vol_decompress_chunk(&req, _read_decompress_done); 183042f59f50SAlexey Marchuk CU_ASSERT(g_reduce_errno == 0); 183142f59f50SAlexey Marchuk CU_ASSERT(req.copy_after_decompress == true); 183242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 183342f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 183442f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 183542f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.iov[0].iov_base, req.decomp_iov[0].iov_base, req.iov[0].iov_len) == 0); 183642f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.iov[1].iov_base, req.decomp_iov[0].iov_base + req.iov[0].iov_len, 183742f59f50SAlexey Marchuk req.iov[1].iov_len) == 0); 18386881fb40SYalong Wang CU_ASSERT(RB_EMPTY(&vol.executing_requests)); 183942f59f50SAlexey Marchuk CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req); 184042f59f50SAlexey Marchuk 1841619b4dbaSAlexey Marchuk /* Test 2 - single user's buffer length equals to chunk_size, buffer is not aligned 1842619b4dbaSAlexey Marchuk * User's buffer is copied */ 1843619b4dbaSAlexey Marchuk memset(unaligned_user_buffer, 0xc, vol.params.chunk_size); 1844619b4dbaSAlexey Marchuk req.iov[0].iov_base = unaligned_user_buffer; 1845619b4dbaSAlexey Marchuk req.iov[0].iov_len = vol.params.chunk_size; 1846619b4dbaSAlexey Marchuk req.iovcnt = 1; 1847619b4dbaSAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 18486881fb40SYalong Wang RB_INSERT(executing_req_tree, &vol.executing_requests, &req); 1849619b4dbaSAlexey Marchuk g_reduce_errno = -1; 1850619b4dbaSAlexey Marchuk 1851619b4dbaSAlexey Marchuk _reduce_vol_decompress_chunk(&req, _read_decompress_done); 1852619b4dbaSAlexey Marchuk CU_ASSERT(g_reduce_errno == 0); 1853619b4dbaSAlexey Marchuk CU_ASSERT(req.copy_after_decompress == true); 1854619b4dbaSAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 1855619b4dbaSAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 1856619b4dbaSAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 1857619b4dbaSAlexey Marchuk CU_ASSERT(memcmp(req.iov[0].iov_base, req.decomp_iov[0].iov_base, 1858619b4dbaSAlexey Marchuk req.iov[0].iov_len) == 0); 1859619b4dbaSAlexey Marchuk 1860619b4dbaSAlexey Marchuk /* Test 3 - single user's buffer length equals to chunk_size 186142f59f50SAlexey Marchuk * User's buffer is not copied */ 1862619b4dbaSAlexey Marchuk req.iov[0].iov_base = aligned_user_buffer; 186342f59f50SAlexey Marchuk req.iov[0].iov_len = vol.params.chunk_size; 186442f59f50SAlexey Marchuk req.iovcnt = 1; 186542f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 18666881fb40SYalong Wang RB_INSERT(executing_req_tree, &vol.executing_requests, &req); 186742f59f50SAlexey Marchuk g_reduce_errno = -1; 186842f59f50SAlexey Marchuk 186942f59f50SAlexey Marchuk _reduce_vol_decompress_chunk(&req, _read_decompress_done); 187042f59f50SAlexey Marchuk CU_ASSERT(g_reduce_errno == 0); 187142f59f50SAlexey Marchuk CU_ASSERT(req.copy_after_decompress == false); 187242f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 187342f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.iov[0].iov_base); 187442f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 187542f59f50SAlexey Marchuk 1876619b4dbaSAlexey Marchuk /* Test 4 - user's buffer less than chunk_size, without offset 187742f59f50SAlexey Marchuk * User's buffers are copied */ 187842f59f50SAlexey Marchuk user_buffer_iov_len = 4096; 187942f59f50SAlexey Marchuk req.iovcnt = 2; 188042f59f50SAlexey Marchuk remainder_bytes = vol.params.chunk_size - user_buffer_iov_len * 2; 188142f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 1882619b4dbaSAlexey Marchuk req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len; 188342f59f50SAlexey Marchuk req.iov[i].iov_len = user_buffer_iov_len; 188442f59f50SAlexey Marchuk memset(req.iov[i].iov_base, 0xb + i, req.iov[i].iov_len); 188542f59f50SAlexey Marchuk } 188642f59f50SAlexey Marchuk 188742f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 18886881fb40SYalong Wang RB_INSERT(executing_req_tree, &vol.executing_requests, &req); 188942f59f50SAlexey Marchuk g_reduce_errno = -1; 189042f59f50SAlexey Marchuk 189142f59f50SAlexey Marchuk _reduce_vol_decompress_chunk(&req, _read_decompress_done); 189242f59f50SAlexey Marchuk CU_ASSERT(g_reduce_errno == 0); 189342f59f50SAlexey Marchuk CU_ASSERT(req.copy_after_decompress == true); 189442f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 189542f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 189642f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 189742f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.iov[0].iov_base, req.decomp_iov[0].iov_base, 189842f59f50SAlexey Marchuk req.iov[0].iov_len) == 0); 189942f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.iov[1].iov_base, req.decomp_iov[0].iov_base + req.iov[0].iov_len, 190042f59f50SAlexey Marchuk req.iov[1].iov_len) == 0); 19016881fb40SYalong Wang CU_ASSERT(RB_EMPTY(&vol.executing_requests)); 190242f59f50SAlexey Marchuk CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req); 190342f59f50SAlexey Marchuk 1904619b4dbaSAlexey Marchuk /* Test 5 - user's buffer less than chunk_size, non zero offset 190542f59f50SAlexey Marchuk * user's buffers are copied */ 190642f59f50SAlexey Marchuk req.offset = 3; 190742f59f50SAlexey Marchuk offset_bytes = req.offset * vol.params.logical_block_size; 190842f59f50SAlexey Marchuk remainder_bytes = vol.params.chunk_size - offset_bytes - user_buffer_iov_len * 2; 190942f59f50SAlexey Marchuk 191042f59f50SAlexey Marchuk for (i = 0; i < 2; i++) { 1911619b4dbaSAlexey Marchuk req.iov[i].iov_base = aligned_user_buffer + i * user_buffer_iov_len; 191242f59f50SAlexey Marchuk req.iov[i].iov_len = user_buffer_iov_len; 191342f59f50SAlexey Marchuk memset(req.iov[i].iov_base, 0xb + i, req.iov[i].iov_len); 191442f59f50SAlexey Marchuk } 191542f59f50SAlexey Marchuk 191642f59f50SAlexey Marchuk memset(req.decomp_buf, 0xa, vol.params.chunk_size); 19176881fb40SYalong Wang RB_INSERT(executing_req_tree, &vol.executing_requests, &req); 191842f59f50SAlexey Marchuk g_reduce_errno = -1; 191942f59f50SAlexey Marchuk 192042f59f50SAlexey Marchuk _prepare_compress_chunk(&req, false); 192142f59f50SAlexey Marchuk _reduce_vol_decompress_chunk(&req, _read_decompress_done); 192242f59f50SAlexey Marchuk CU_ASSERT(g_reduce_errno == 0); 192342f59f50SAlexey Marchuk CU_ASSERT(req.copy_after_decompress == true); 192442f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iovcnt == 1); 192542f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_base == req.decomp_buf); 192642f59f50SAlexey Marchuk CU_ASSERT(req.decomp_iov[0].iov_len == vol.params.chunk_size); 192742f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + offset_bytes, req.iov[0].iov_base, 192842f59f50SAlexey Marchuk req.iov[0].iov_len) == 0); 192942f59f50SAlexey Marchuk CU_ASSERT(memcmp(req.decomp_iov[0].iov_base + offset_bytes + req.iov[0].iov_len, 193042f59f50SAlexey Marchuk req.iov[1].iov_base, 193142f59f50SAlexey Marchuk req.iov[1].iov_len) == 0); 19326881fb40SYalong Wang CU_ASSERT(RB_EMPTY(&vol.executing_requests)); 193342f59f50SAlexey Marchuk CU_ASSERT(TAILQ_FIRST(&vol.free_requests) == &req); 1934619b4dbaSAlexey Marchuk 1935619b4dbaSAlexey Marchuk free(buf); 193642f59f50SAlexey Marchuk } 193742f59f50SAlexey Marchuk 19388dd1cd21SBen Walker static void 19398dd1cd21SBen Walker test_allocate_vol_requests(void) 1940b86e85f5SAlexey Marchuk { 1941b86e85f5SAlexey Marchuk struct spdk_reduce_vol *vol; 1942245271b6SYankun Li struct spdk_reduce_backing_dev backing_dev = {}; 1943b86e85f5SAlexey Marchuk /* include chunk_sizes which are not power of 2 */ 1944b86e85f5SAlexey Marchuk uint32_t chunk_sizes[] = {8192, 8320, 16384, 16416, 32768}; 1945b86e85f5SAlexey Marchuk uint32_t io_unit_sizes[] = {512, 520, 4096, 4104, 4096}; 1946b86e85f5SAlexey Marchuk uint32_t i; 1947b86e85f5SAlexey Marchuk 1948245271b6SYankun Li /* bdev compress module can specify how big the user_ctx_size needs to be */ 1949245271b6SYankun Li backing_dev.user_ctx_size = 64; 1950b86e85f5SAlexey Marchuk for (i = 0; i < 4; i++) { 1951b86e85f5SAlexey Marchuk vol = calloc(1, sizeof(*vol)); 1952b86e85f5SAlexey Marchuk SPDK_CU_ASSERT_FATAL(vol); 1953b86e85f5SAlexey Marchuk 1954b86e85f5SAlexey Marchuk vol->params.chunk_size = chunk_sizes[i]; 1955b86e85f5SAlexey Marchuk vol->params.logical_block_size = io_unit_sizes[i]; 1956b86e85f5SAlexey Marchuk vol->params.backing_io_unit_size = io_unit_sizes[i]; 1957b86e85f5SAlexey Marchuk vol->backing_io_units_per_chunk = vol->params.chunk_size / vol->params.backing_io_unit_size; 1958b86e85f5SAlexey Marchuk vol->logical_blocks_per_chunk = vol->params.chunk_size / vol->params.logical_block_size; 1959245271b6SYankun Li vol->backing_dev = &backing_dev; 1960b86e85f5SAlexey Marchuk 1961b86e85f5SAlexey Marchuk CU_ASSERT(_validate_vol_params(&vol->params) == 0); 1962b86e85f5SAlexey Marchuk CU_ASSERT(_allocate_vol_requests(vol) == 0); 1963b86e85f5SAlexey Marchuk _init_load_cleanup(vol, NULL); 1964b86e85f5SAlexey Marchuk } 1965b86e85f5SAlexey Marchuk } 1966b86e85f5SAlexey Marchuk 19676bf35070SJim Harris int 19686bf35070SJim Harris main(int argc, char **argv) 19696bf35070SJim Harris { 19706bf35070SJim Harris CU_pSuite suite = NULL; 19716bf35070SJim Harris unsigned int num_failures; 19726bf35070SJim Harris 197378b696bcSVitaliy Mysak CU_initialize_registry(); 19746bf35070SJim Harris 19756bf35070SJim Harris suite = CU_add_suite("reduce", NULL, NULL); 19766bf35070SJim Harris 1977*412fced1SYalong Wang spdk_thread_lib_init(NULL, 0); 1978*412fced1SYalong Wang g_thread = spdk_thread_create(NULL, NULL); 1979*412fced1SYalong Wang spdk_set_thread(g_thread); 1980*412fced1SYalong Wang 1981dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, get_pm_file_size); 1982dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, get_vol_size); 1983dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, init_failure); 1984dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, init_md); 1985dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, init_backing_dev); 1986dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, load); 1987dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, write_maps); 1988dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, read_write); 1989dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, readv_writev); 1990*412fced1SYalong Wang CU_ADD_TEST(suite, write_unmap_verify); 1991dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, destroy); 1992dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, defer_bdev_io); 1993dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, overlapped); 1994dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, compress_algorithm); 199542f59f50SAlexey Marchuk CU_ADD_TEST(suite, test_prepare_compress_chunk); 199642f59f50SAlexey Marchuk CU_ADD_TEST(suite, test_reduce_decompress_chunk); 1997b86e85f5SAlexey Marchuk CU_ADD_TEST(suite, test_allocate_vol_requests); 19986bf35070SJim Harris 1999cfb65ba6SJim Harris g_unlink_path = g_path; 2000cfb65ba6SJim Harris g_unlink_callback = unlink_cb; 2001cfb65ba6SJim Harris 2002ea941caeSKonrad Sztyber num_failures = spdk_ut_run_tests(argc, argv, NULL); 2003*412fced1SYalong Wang 2004*412fced1SYalong Wang spdk_thread_exit(g_thread); 2005*412fced1SYalong Wang while (!spdk_thread_is_exited(g_thread)) { 2006*412fced1SYalong Wang spdk_thread_poll(g_thread, 0, 0); 2007*412fced1SYalong Wang } 2008*412fced1SYalong Wang spdk_thread_destroy(g_thread); 2009*412fced1SYalong Wang spdk_thread_lib_fini(); 2010*412fced1SYalong Wang 20116bf35070SJim Harris CU_cleanup_registry(); 20126bf35070SJim Harris return num_failures; 20136bf35070SJim Harris } 2014