From 69fa57cdf0795cd177ff2fdb2ec983c523dad7a5 Mon Sep 17 00:00:00 2001 From: Piotr Pelplinski Date: Thu, 26 Apr 2018 14:21:35 +0200 Subject: [PATCH] blobstore: freeze I/O during resize Signed-off-by: Piotr Pelplinski Change-Id: I23c34d4dcb542aa9ab3fa8cb734cf9cc0e0fc5da Reviewed-on: https://review.gerrithub.io/409144 Tested-by: SPDK Automated Test System Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- include/spdk/blob.h | 1 + lib/blob/blobstore.c | 66 ++++++++++++++++++++++++++++++++++++++++++-- lib/blob/blobstore.h | 1 + 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/include/spdk/blob.h b/include/spdk/blob.h index 3c813e332..cce547187 100644 --- a/include/spdk/blob.h +++ b/include/spdk/blob.h @@ -534,6 +534,7 @@ void spdk_bs_open_blob(struct spdk_blob_store *bs, spdk_blob_id blobid, /** * Resize a blob to 'sz' clusters. These changes are not persisted to disk until * spdk_bs_md_sync_blob() is called. + * If called before previous resize finish, it will fail with errno -EBUSY * * \param blob Blob to resize. * \param sz The new number of clusters. diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index a1f7625cc..8d5abb2e6 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -4441,10 +4441,55 @@ void spdk_bs_inflate_blob(struct spdk_blob_store *bs, struct spdk_io_channel *ch /* END spdk_bs_inflate_blob */ /* START spdk_blob_resize */ +struct spdk_bs_resize_ctx { + spdk_blob_op_complete cb_fn; + void *cb_arg; + struct spdk_blob *blob; + uint64_t sz; + int rc; +}; + +static void +_spdk_bs_resize_unfreeze_cpl(void *cb_arg, int rc) +{ + struct spdk_bs_resize_ctx *ctx = (struct spdk_bs_resize_ctx *)cb_arg; + + if (rc != 0) { + SPDK_ERRLOG("Unfreeze failed, rc=%d\n", rc); + } + + if (ctx->rc != 0) { + SPDK_ERRLOG("Unfreeze failed, ctx->rc=%d\n", ctx->rc); + rc = ctx->rc; + } + + ctx->blob->resize_in_progress = false; + + ctx->cb_fn(ctx->cb_arg, rc); + free(ctx); +} + +static void +_spdk_bs_resize_freeze_cpl(void *cb_arg, int rc) +{ + struct spdk_bs_resize_ctx *ctx = (struct spdk_bs_resize_ctx *)cb_arg; + + if (rc != 0) { + ctx->blob->resize_in_progress = false; + ctx->cb_fn(ctx->cb_arg, rc); + free(ctx); + return; + } + + ctx->rc = _spdk_blob_resize(ctx->blob, ctx->sz); + + _spdk_blob_unfreeze_io(ctx->blob, _spdk_bs_resize_unfreeze_cpl, ctx); +} + void spdk_blob_resize(struct spdk_blob *blob, uint64_t sz, spdk_blob_op_complete cb_fn, void *cb_arg) { - int rc; + struct spdk_bs_resize_ctx *ctx; _spdk_blob_verify_md_op(blob); @@ -4460,8 +4505,23 @@ spdk_blob_resize(struct spdk_blob *blob, uint64_t sz, spdk_blob_op_complete cb_f return; } - rc = _spdk_blob_resize(blob, sz); - cb_fn(cb_arg, rc); + if (blob->resize_in_progress) { + cb_fn(cb_arg, -EBUSY); + return; + } + + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) { + cb_fn(cb_arg, -ENOMEM); + return; + } + + blob->resize_in_progress = true; + ctx->cb_fn = cb_fn; + ctx->cb_arg = cb_arg; + ctx->blob = blob; + ctx->sz = sz; + _spdk_blob_freeze_io(blob, _spdk_bs_resize_freeze_cpl, ctx); } /* END spdk_blob_resize */ diff --git a/lib/blob/blobstore.h b/lib/blob/blobstore.h index b2e3cd6ea..2084e5cfe 100644 --- a/lib/blob/blobstore.h +++ b/lib/blob/blobstore.h @@ -149,6 +149,7 @@ struct spdk_blob { TAILQ_ENTRY(spdk_blob) link; uint32_t frozen_refcnt; + bool resize_in_progress; }; struct spdk_blob_store {