From 6ce7a7391233eea7c446ef125a2c1f00346265ee Mon Sep 17 00:00:00 2001 From: Maciej Szwed Date: Mon, 23 Apr 2018 14:30:16 +0200 Subject: [PATCH] lvol: add lvol inflate function Change-Id: Ib999d3f082f5d632cb1aaf089504d0cd48e77539 Signed-off-by: Maciej Szwed Signed-off-by: Tomasz Kulasek Reviewed-on: https://review.gerrithub.io/408696 Reviewed-by: Daniel Verkamp Reviewed-by: Shuhei Matsumoto Reviewed-by: Ben Walker Tested-by: SPDK Automated Test System --- include/spdk/lvol.h | 9 ++++ include/spdk_internal/lvolstore.h | 1 + lib/lvol/lvol.c | 51 ++++++++++++++++++ test/unit/lib/lvol/lvol.c/lvol_ut.c | 81 ++++++++++++++++++++++++++++- 4 files changed, 140 insertions(+), 2 deletions(-) diff --git a/include/spdk/lvol.h b/include/spdk/lvol.h index f87b141cf4..15d85d140a 100644 --- a/include/spdk/lvol.h +++ b/include/spdk/lvol.h @@ -251,6 +251,15 @@ void spdk_lvs_load(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete */ void spdk_lvol_open(struct spdk_lvol *lvol, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg); +/** + * Inflate lvol + * + * \param lvol Handle to lvol + * \param cb_fn Completion callback + * \param cb_arg Completion callback custom arguments + */ +void spdk_lvol_inflate(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg); + #ifdef __cplusplus } #endif diff --git a/include/spdk_internal/lvolstore.h b/include/spdk_internal/lvolstore.h index 89557a6815..30cff2155c 100644 --- a/include/spdk_internal/lvolstore.h +++ b/include/spdk_internal/lvolstore.h @@ -54,6 +54,7 @@ struct spdk_lvol_req { void *cb_arg; struct spdk_lvol *lvol; size_t sz; + struct spdk_io_channel *channel; char name[SPDK_LVOL_NAME_MAX]; }; diff --git a/lib/lvol/lvol.c b/lib/lvol/lvol.c index 00487ce059..dca14a4915 100644 --- a/lib/lvol/lvol.c +++ b/lib/lvol/lvol.c @@ -1423,3 +1423,54 @@ spdk_lvol_get_io_channel(struct spdk_lvol *lvol) { return spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); } + +static void +_spdk_lvol_inflate_cb(void *cb_arg, int lvolerrno) +{ + struct spdk_lvol_req *req = cb_arg; + + spdk_bs_free_io_channel(req->channel); + + if (lvolerrno < 0) { + SPDK_ERRLOG("Could not inflate lvol\n"); + } + + req->cb_fn(req->cb_arg, lvolerrno); + free(req); +} + +void +spdk_lvol_inflate(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) +{ + struct spdk_lvol_req *req; + struct spdk_blob *blob = lvol->blob; + spdk_blob_id blob_id = spdk_blob_get_id(blob); + + assert(cb_fn != NULL); + + if (lvol == NULL) { + SPDK_ERRLOG("Lvol does not exist\n"); + cb_fn(cb_arg, -ENODEV); + return; + } + + req = calloc(1, sizeof(*req)); + if (!req) { + SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); + cb_fn(cb_arg, -ENOMEM); + return; + } + + req->cb_fn = cb_fn; + req->cb_arg = cb_arg; + req->channel = spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); + if (req->channel == NULL) { + SPDK_ERRLOG("Cannot alloc io channel for lvol inflate request\n"); + free(req); + cb_fn(cb_arg, -ENOMEM); + return; + } + + spdk_bs_inflate_blob(lvol->lvol_store->blobstore, req->channel, blob_id, _spdk_lvol_inflate_cb, + req); +} diff --git a/test/unit/lib/lvol/lvol.c/lvol_ut.c b/test/unit/lib/lvol/lvol.c/lvol_ut.c index e56b624189..9f9455dedb 100644 --- a/test/unit/lib/lvol/lvol.c/lvol_ut.c +++ b/test/unit/lib/lvol/lvol.c/lvol_ut.c @@ -73,10 +73,12 @@ int g_lvolerrno; int g_lvserrno; int g_close_super_status; int g_resize_rc; +int g_inflate_rc; bool g_lvs_rename_blob_open_error = false; struct spdk_lvol_store *g_lvol_store; struct spdk_lvol *g_lvol; spdk_blob_id g_blobid = 1; +struct spdk_io_channel *g_io_channel; struct spdk_blob_store { struct spdk_bs_opts bs_opts; @@ -92,6 +94,12 @@ struct lvol_ut_bs_dev { struct spdk_blob_store *bs; }; +void spdk_bs_inflate_blob(struct spdk_blob_store *bs, struct spdk_io_channel *channel, + spdk_blob_id blobid, spdk_blob_op_complete cb_fn, void *cb_arg) +{ + cb_fn(cb_arg, g_inflate_rc); +} + void spdk_bs_iter_next(struct spdk_blob_store *bs, struct spdk_blob *b, spdk_blob_op_with_handle_complete cb_fn, void *cb_arg) @@ -166,7 +174,22 @@ spdk_bs_load(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts, struct spdk_io_channel *spdk_bs_alloc_io_channel(struct spdk_blob_store *bs) { - return NULL; + if (g_io_channel == NULL) { + g_io_channel = calloc(1, sizeof(struct spdk_io_channel)); + SPDK_CU_ASSERT_FATAL(g_io_channel != NULL); + } + g_io_channel->ref++; + return g_io_channel; +} + +void spdk_bs_free_io_channel(struct spdk_io_channel *channel) +{ + g_io_channel->ref--; + if (g_io_channel->ref == 0) { + free(g_io_channel); + g_io_channel = NULL; + } + return; } int @@ -1924,6 +1947,59 @@ lvol_create_thin_provisioned(void) spdk_free_thread(); } +static void +lvol_inflate(void) +{ + struct lvol_ut_bs_dev dev; + struct spdk_lvs_opts opts; + int rc = 0; + + init_dev(&dev); + + spdk_allocate_thread(_lvol_send_msg, NULL, NULL, NULL, NULL); + + spdk_lvs_opts_init(&opts); + snprintf(opts.name, sizeof(opts.name), "lvs"); + + g_lvserrno = -1; + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + CU_ASSERT(rc == 0); + CU_ASSERT(g_lvserrno == 0); + SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); + + spdk_lvol_create(g_lvol_store, "lvol", 10, false, lvol_op_with_handle_complete, NULL); + CU_ASSERT(g_lvserrno == 0); + SPDK_CU_ASSERT_FATAL(g_lvol != NULL); + + g_inflate_rc = -1; + spdk_lvol_inflate(g_lvol, lvol_op_complete, NULL); + CU_ASSERT(g_lvolerrno != 0); + + g_inflate_rc = 0; + spdk_lvol_inflate(g_lvol, lvol_op_complete, NULL); + CU_ASSERT(g_lvolerrno == 0); + + spdk_lvol_close(g_lvol, close_cb, NULL); + CU_ASSERT(g_lvserrno == 0); + spdk_lvol_destroy(g_lvol, destroy_cb, NULL); + CU_ASSERT(g_lvserrno == 0); + + g_lvserrno = -1; + rc = spdk_lvs_unload(g_lvol_store, lvol_store_op_complete, NULL); + CU_ASSERT(rc == 0); + CU_ASSERT(g_lvserrno == 0); + g_lvol_store = NULL; + + free_dev(&dev); + + /* Make sure that all references to the io_channel was closed after + * inflate call + */ + CU_ASSERT(g_io_channel == NULL); + + spdk_free_thread(); +} + int main(int argc, char **argv) { CU_pSuite suite = NULL; @@ -1965,7 +2041,8 @@ int main(int argc, char **argv) CU_add_test(suite, "lvol_names", lvol_names) == NULL || CU_add_test(suite, "lvol_create_thin_provisioned", lvol_create_thin_provisioned) == NULL || CU_add_test(suite, "lvol_rename", lvol_rename) == NULL || - CU_add_test(suite, "lvs_rename", lvs_rename) == NULL + CU_add_test(suite, "lvs_rename", lvs_rename) == NULL || + CU_add_test(suite, "lvol_inflate", lvol_inflate) == NULL ) { CU_cleanup_registry(); return CU_get_error();