blob: persist super_blob id on blobstore immediately

Before this patch super_blob id for blobstore was persisted
only during spdk_bs_unload. If power fail occurred after creating and
syncing blob, super_blob id was lost within blobstore.

Lvol store metadata would be lost, if proper shutdown
didn't occur in first SPDK instance run since creation of lvs.

This fix changes setting super blob to be instantly persisted
on disk in super block. Without affecting clean bit in super block.

Change-Id: I578f1fc8717e2d7968ad506fa4dead7507a5e0b4
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.gerrithub.io/398804
Reviewed-by: Maciej Szwed <maciej.szwed@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Tomasz Zawadzki 2018-02-07 09:14:43 -05:00 committed by Daniel Verkamp
parent 2a274cc987
commit b86c4b6541
2 changed files with 90 additions and 3 deletions

View File

@ -3144,14 +3144,92 @@ spdk_bs_unload(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn, void *cb_a
/* END spdk_bs_unload */
/* START spdk_bs_set_super */
struct spdk_bs_set_super_ctx {
struct spdk_blob_store *bs;
struct spdk_bs_super_block *super;
};
static void
_spdk_bs_set_super_write_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
{
struct spdk_bs_set_super_ctx *ctx = cb_arg;
if (bserrno != 0) {
SPDK_ERRLOG("Unable to write to super block of blobstore\n");
}
spdk_dma_free(ctx->super);
spdk_bs_sequence_finish(seq, bserrno);
free(ctx);
}
static void
_spdk_bs_set_super_read_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
{
struct spdk_bs_set_super_ctx *ctx = cb_arg;
if (bserrno != 0) {
SPDK_ERRLOG("Unable to read super block of blobstore\n");
spdk_dma_free(ctx->super);
spdk_bs_sequence_finish(seq, bserrno);
free(ctx);
return;
}
_spdk_bs_write_super(seq, ctx->bs, ctx->super, _spdk_bs_set_super_write_cpl, ctx);
}
void
spdk_bs_set_super(struct spdk_blob_store *bs, spdk_blob_id blobid,
spdk_bs_op_complete cb_fn, void *cb_arg)
{
struct spdk_bs_cpl cpl;
spdk_bs_sequence_t *seq;
struct spdk_bs_set_super_ctx *ctx;
SPDK_DEBUGLOG(SPDK_LOG_BLOB, "Setting super blob id on blobstore\n");
ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
cb_fn(cb_arg, -ENOMEM);
return;
}
ctx->bs = bs;
ctx->super = spdk_dma_zmalloc(sizeof(*ctx->super), 0x1000, NULL);
if (!ctx->super) {
free(ctx);
cb_fn(cb_arg, -ENOMEM);
return;
}
cpl.type = SPDK_BS_CPL_TYPE_BS_BASIC;
cpl.u.bs_basic.cb_fn = cb_fn;
cpl.u.bs_basic.cb_arg = cb_arg;
seq = spdk_bs_sequence_start(bs->md_channel, &cpl);
if (!seq) {
spdk_dma_free(ctx->super);
free(ctx);
cb_fn(cb_arg, -ENOMEM);
return;
}
bs->super_blob = blobid;
cb_fn(cb_arg, 0);
/* Read super block */
spdk_bs_sequence_read_dev(seq, ctx->super, _spdk_bs_page_to_lba(bs, 0),
_spdk_bs_byte_to_lba(bs, sizeof(*ctx->super)),
_spdk_bs_set_super_read_cpl, ctx);
}
/* END spdk_bs_set_super */
void
spdk_bs_get_super(struct spdk_blob_store *bs,
spdk_blob_op_with_id_complete cb_fn, void *cb_arg)

View File

@ -2063,13 +2063,13 @@ super_block_crc(void)
}
/* For blob dirty shutdown test case we do the following sub-test cases:
* 1 Initialize new blob store and create 1 blob with some xattrs, then we
* 1 Initialize new blob store and create 1 super blob with some xattrs, then we
* dirty shutdown and reload the blob store and verify the xattrs.
* 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
* reload the blob store and verify the clusters number.
* 3 Create the second blob and then dirty shutdown, reload the blob store
* and verify the second blob.
* 4 Delete the second blob and then dirty shutdown, reload teh blob store
* 4 Delete the second blob and then dirty shutdown, reload the blob store
* and verify the second blob is invalid.
* 5 Create the second blob again and also create the third blob, modify the
* md of second blob which makes the md invalid, and then dirty shutdown,
@ -2122,6 +2122,10 @@ blob_dirty_shutdown(void)
rc = spdk_blob_resize(blob, 10);
CU_ASSERT(rc == 0);
/* Set the blob as the super blob */
spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
free_clusters = spdk_bs_free_cluster_count(g_bs);
spdk_blob_close(blob, blob_op_complete, NULL);
@ -2138,6 +2142,11 @@ blob_dirty_shutdown(void)
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == 0);
/* Get the super blob */
spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(blobid1 == g_blobid);
spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(g_blob != NULL);