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:
parent
c887a4f9cf
commit
c0f3805153
@ -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.
|
||||
*
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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(¶ms.uuid);
|
||||
|
||||
backing_dev_init(&backing_dev, ¶ms, 512);
|
||||
|
||||
g_vol = NULL;
|
||||
g_reduce_errno = -1;
|
||||
spdk_reduce_vol_init(¶ms, &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();
|
||||
|
Loading…
Reference in New Issue
Block a user