reduce: add spdk_reduce_vol_destroy

This will remove the metadata from the associated backing
device and delete the pm_file associated with the reduce
volume.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I30ffd68e5ba69b31ee1be85418c5b8c592d82e70

Reviewed-on: https://review.gerrithub.io/c/437995
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: wuzhouhui <wuzhouhui@kingsoft.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Jim Harris 2018-12-20 02:45:42 -07:00
parent c887a4f9cf
commit c0f3805153
4 changed files with 173 additions and 1 deletions

View File

@ -158,6 +158,22 @@ void spdk_reduce_vol_unload(struct spdk_reduce_vol *vol,
spdk_reduce_vol_op_complete cb_fn,
void *cb_arg);
/**
* Destroy an existing libreduce compressed volume.
*
* This will zero the metadata region on the backing device and delete the associated
* pm metadata file. If the backing device does not contain a compressed volume, the
* cb_fn will be called with error status without modifying the backing device nor
* deleting a pm file.
*
* \param backing_dev Structure describing the backing device containing the compressed volume.
* \param cb_fn Callback function to signal completion of the destruction process.
* \param cb_arg Argument to pass to the callback function.
*/
void spdk_reduce_vol_destroy(struct spdk_reduce_backing_dev *backing_dev,
spdk_reduce_vol_op_complete cb_fn,
void *cb_arg);
/**
* Read data from a libreduce compressed volume.
*

View File

@ -704,6 +704,94 @@ spdk_reduce_vol_unload(struct spdk_reduce_vol *vol,
cb_fn(cb_arg, 0);
}
struct reduce_destroy_ctx {
spdk_reduce_vol_op_complete cb_fn;
void *cb_arg;
struct spdk_reduce_vol *vol;
struct spdk_reduce_vol_superblock *super;
struct iovec iov;
struct spdk_reduce_vol_cb_args backing_cb_args;
int reduce_errno;
char pm_path[REDUCE_PATH_MAX];
};
static void
destroy_unload_cpl(void *cb_arg, int reduce_errno)
{
struct reduce_destroy_ctx *destroy_ctx = cb_arg;
if (destroy_ctx->reduce_errno == 0) {
if (unlink(destroy_ctx->pm_path)) {
SPDK_ERRLOG("%s could not be unlinked: %s\n",
destroy_ctx->pm_path, strerror(errno));
}
}
/* Even if the unload somehow failed, we still pass the destroy_ctx
* reduce_errno since that indicates whether or not the volume was
* actually destroyed.
*/
destroy_ctx->cb_fn(destroy_ctx->cb_arg, destroy_ctx->reduce_errno);
spdk_dma_free(destroy_ctx->super);
free(destroy_ctx);
}
static void
_destroy_zero_super_cpl(void *cb_arg, int reduce_errno)
{
struct reduce_destroy_ctx *destroy_ctx = cb_arg;
struct spdk_reduce_vol *vol = destroy_ctx->vol;
destroy_ctx->reduce_errno = reduce_errno;
spdk_reduce_vol_unload(vol, destroy_unload_cpl, destroy_ctx);
}
static void
destroy_load_cb(void *cb_arg, struct spdk_reduce_vol *vol, int reduce_errno)
{
struct reduce_destroy_ctx *destroy_ctx = cb_arg;
if (reduce_errno != 0) {
destroy_ctx->cb_fn(destroy_ctx->cb_arg, reduce_errno);
spdk_dma_free(destroy_ctx->super);
free(destroy_ctx);
return;
}
destroy_ctx->vol = vol;
memcpy(destroy_ctx->pm_path, vol->pm_file.path, sizeof(destroy_ctx->pm_path));
destroy_ctx->iov.iov_base = destroy_ctx->super;
destroy_ctx->iov.iov_len = sizeof(*destroy_ctx->super);
destroy_ctx->backing_cb_args.cb_fn = _destroy_zero_super_cpl;
destroy_ctx->backing_cb_args.cb_arg = destroy_ctx;
vol->backing_dev->writev(vol->backing_dev, &destroy_ctx->iov, 1, 0,
sizeof(*destroy_ctx->super) / vol->backing_dev->blocklen,
&destroy_ctx->backing_cb_args);
}
void
spdk_reduce_vol_destroy(struct spdk_reduce_backing_dev *backing_dev,
spdk_reduce_vol_op_complete cb_fn, void *cb_arg)
{
struct reduce_destroy_ctx *destroy_ctx;
destroy_ctx = calloc(1, sizeof(*destroy_ctx));
if (destroy_ctx == NULL) {
cb_fn(cb_arg, -ENOMEM);
return;
}
destroy_ctx->super = spdk_dma_zmalloc(sizeof(*destroy_ctx->super), 64, NULL);
if (destroy_ctx->super == NULL) {
free(destroy_ctx);
cb_fn(cb_arg, -ENOMEM);
return;
}
destroy_ctx->cb_fn = cb_fn;
destroy_ctx->cb_arg = cb_arg;
spdk_reduce_vol_load(backing_dev, destroy_load_cb, destroy_ctx);
}
static bool
_request_spans_chunk_boundary(struct spdk_reduce_vol *vol, uint64_t offset, uint64_t length)
{

View File

@ -35,5 +35,6 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
TEST_FILE = reduce_ut.c
LDFLAGS += -Wl,--wrap,unlink
include $(SPDK_ROOT_DIR)/mk/spdk.unittest.mk

View File

@ -152,6 +152,19 @@ persistent_pm_buf_destroy(void)
g_persistent_pm_buf_len = 0;
}
int __wrap_unlink(const char *path);
int
__wrap_unlink(const char *path)
{
if (strcmp(g_path, path) != 0) {
return ENOENT;
}
persistent_pm_buf_destroy();
return 0;
}
static void
init_cb(void *cb_arg, struct spdk_reduce_vol *vol, int reduce_errno)
{
@ -676,6 +689,59 @@ read_write(void)
_read_write(4096);
}
static void
destroy_cb(void *ctx, int reduce_errno)
{
g_reduce_errno = reduce_errno;
}
static void
destroy(void)
{
struct spdk_reduce_vol_params params = {};
struct spdk_reduce_backing_dev backing_dev = {};
params.chunk_size = 16 * 1024;
params.backing_io_unit_size = 512;
params.logical_block_size = 512;
spdk_uuid_generate(&params.uuid);
backing_dev_init(&backing_dev, &params, 512);
g_vol = NULL;
g_reduce_errno = -1;
spdk_reduce_vol_init(&params, &backing_dev, TEST_MD_PATH, init_cb, NULL);
CU_ASSERT(g_reduce_errno == 0);
SPDK_CU_ASSERT_FATAL(g_vol != NULL);
g_reduce_errno = -1;
spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
CU_ASSERT(g_reduce_errno == 0);
g_vol = NULL;
g_reduce_errno = -1;
spdk_reduce_vol_load(&backing_dev, load_cb, NULL);
CU_ASSERT(g_reduce_errno == 0);
SPDK_CU_ASSERT_FATAL(g_vol != NULL);
g_reduce_errno = -1;
spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
CU_ASSERT(g_reduce_errno == 0);
g_reduce_errno = -1;
MOCK_CLEAR(spdk_dma_zmalloc);
MOCK_CLEAR(spdk_malloc);
MOCK_CLEAR(spdk_zmalloc);
spdk_reduce_vol_destroy(&backing_dev, destroy_cb, NULL);
CU_ASSERT(g_reduce_errno == 0);
g_reduce_errno = 0;
spdk_reduce_vol_load(&backing_dev, load_cb, NULL);
CU_ASSERT(g_reduce_errno == -EILSEQ);
backing_dev_destroy(&backing_dev);
}
int
main(int argc, char **argv)
{
@ -700,7 +766,8 @@ main(int argc, char **argv)
CU_add_test(suite, "init_backing_dev", init_backing_dev) == NULL ||
CU_add_test(suite, "load", load) == NULL ||
CU_add_test(suite, "write_maps", write_maps) == NULL ||
CU_add_test(suite, "read_write", read_write) == NULL
CU_add_test(suite, "read_write", read_write) == NULL ||
CU_add_test(suite, "destroy", destroy) == NULL
) {
CU_cleanup_registry();
return CU_get_error();