From 63ba545f546307b7efd7c6250bdebdf88bdc7adf Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Wed, 3 Oct 2018 00:37:16 -0700 Subject: [PATCH] reduce: rebuild bit arrays during load This requires fixing up the unit test pmem emulation code - we need to copy the 'persistent' buffer into the newly 'mmaped' buffer in the pmem_map_file stub. Signed-off-by: Jim Harris Change-Id: I4e474f437922e652a57d0b45b6ef92fc713eb587 Reviewed-on: https://review.gerrithub.io/c/437888 Tested-by: SPDK CI Jenkins Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Shuhei Matsumoto Reviewed-by: Changpeng Liu --- lib/reduce/reduce.c | 18 ++++++++++ test/unit/lib/reduce/reduce.c/reduce_ut.c | 42 +++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/lib/reduce/reduce.c b/lib/reduce/reduce.c index 045f52827..65598a00a 100644 --- a/lib/reduce/reduce.c +++ b/lib/reduce/reduce.c @@ -546,7 +546,10 @@ _load_read_super_and_path_cpl(void *cb_arg, int reduce_errno) struct reduce_init_load_ctx *load_ctx = cb_arg; struct spdk_reduce_vol *vol = load_ctx->vol; uint64_t backing_dev_size; + uint64_t i, num_chunks; + uint64_t *chunk; size_t mapped_len; + uint32_t j; int rc; if (memcmp(vol->backing_super->signature, @@ -598,6 +601,21 @@ _load_read_super_and_path_cpl(void *cb_arg, int reduce_errno) } _initialize_vol_pm_pointers(vol); + + num_chunks = vol->params.vol_size / vol->params.chunk_size; + for (i = 0; i < num_chunks; i++) { + if (vol->pm_logical_map[i] == REDUCE_EMPTY_MAP_ENTRY) { + continue; + } + spdk_bit_array_set(vol->allocated_chunk_maps, i); + chunk = _reduce_vol_get_chunk_map(vol, i); + for (j = 0; j < vol->backing_io_units_per_chunk; j++) { + if (chunk[j] != REDUCE_EMPTY_MAP_ENTRY) { + spdk_bit_array_set(vol->allocated_backing_io_units, chunk[j]); + } + } + } + load_ctx->cb_fn(load_ctx->cb_arg, vol, 0); /* Only clean up the ctx - the vol has been passed to the application * for use now that volume load was successful. diff --git a/test/unit/lib/reduce/reduce.c/reduce_ut.c b/test/unit/lib/reduce/reduce.c/reduce_ut.c index 4e51bee22..f5960078e 100644 --- a/test/unit/lib/reduce/reduce.c/reduce_ut.c +++ b/test/unit/lib/reduce/reduce.c/reduce_ut.c @@ -125,6 +125,7 @@ pmem_map_file(const char *path, size_t len, int flags, mode_t mode, *mapped_lenp = g_persistent_pm_buf_len; g_volatile_pm_buf = calloc(1, g_persistent_pm_buf_len); SPDK_CU_ASSERT_FATAL(g_volatile_pm_buf != NULL); + memcpy(g_volatile_pm_buf, g_persistent_pm_buf, g_persistent_pm_buf_len); g_volatile_pm_buf_len = g_persistent_pm_buf_len; return g_volatile_pm_buf; @@ -620,6 +621,47 @@ _read_write(uint32_t backing_blocklen) CU_ASSERT(g_vol->params.chunk_size == params.chunk_size); CU_ASSERT(g_vol->params.backing_io_unit_size == params.backing_io_unit_size); + g_reduce_errno = -1; + + /* Write 0xBB to 2 512-byte logical blocks, starting at LBA 37. + * This is writing into the second chunk of the volume. This also + * enables implicitly checking that we reloaded the bit arrays + * correctly - making sure we don't use the first chunk map again + * for this new write - the first chunk map was already used by the + * write from before we unloaded and reloaded. + */ + memset(buf, 0xBB, 2 * params.logical_block_size); + iov.iov_base = buf; + iov.iov_len = 2 * params.logical_block_size; + g_reduce_errno = -1; + spdk_reduce_vol_writev(g_vol, &iov, 1, 37, 2, write_cb, NULL); + CU_ASSERT(g_reduce_errno == 0); + + for (i = 0; i < 2 * params.chunk_size / params.logical_block_size; i++) { + memset(buf, 0xFF, params.logical_block_size); + iov.iov_base = buf; + iov.iov_len = params.logical_block_size; + g_reduce_errno = -1; + spdk_reduce_vol_readv(g_vol, &iov, 1, i, 1, read_cb, NULL); + CU_ASSERT(g_reduce_errno == 0); + + switch (i) { + case 2: + case 3: + memset(compare_buf, 0xAA, sizeof(compare_buf)); + CU_ASSERT(memcmp(buf, compare_buf, params.logical_block_size) == 0); + break; + case 37: + case 38: + memset(compare_buf, 0xBB, sizeof(compare_buf)); + CU_ASSERT(memcmp(buf, compare_buf, params.logical_block_size) == 0); + break; + default: + CU_ASSERT(spdk_mem_all_zero(buf, params.logical_block_size)); + break; + } + } + g_reduce_errno = -1; spdk_reduce_vol_unload(g_vol, unload_cb, NULL); CU_ASSERT(g_reduce_errno == 0);