From e87808c4fbcf7c5139d70a9ed2d7ad728a6366c0 Mon Sep 17 00:00:00 2001 From: Cunyin Chang Date: Wed, 30 Aug 2017 11:08:18 +0800 Subject: [PATCH] blobstore: sync super block after set the "clean" as 0. The system could crash anytime, we need sync the "clean" flag into disk as soon as we load the blobstore. Then if the system crashed, we will find the blobstore is not clean shutdown next time when we load the blobstore, and we could run the recover process then. Change-Id: I6189678e970ffe979a224e02be6cede0ee44dde8 Signed-off-by: Cunyin Chang Reviewed-on: https://review.gerrithub.io/376276 Tested-by: SPDK Automated Test System Reviewed-by: Ben Walker Reviewed-by: Jim Harris Reviewed-by: Daniel Verkamp Reviewed-by: Paul Luse --- lib/blob/blobstore.c | 58 +++++++++++++++++------------ test/unit/lib/blob/blob.c/blob_ut.c | 6 +++ 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index dd6251d5d..91a040322 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -1485,11 +1485,41 @@ _spdk_bs_load_used_pages_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) _spdk_bs_load_used_clusters_cpl, ctx); } +static void +_spdk_bs_load_write_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) +{ + struct spdk_bs_load_ctx *ctx = cb_arg; + uint64_t lba, lba_count, mask_size; + + /* Parse the super block */ + ctx->bs->cluster_sz = ctx->super->cluster_size; + ctx->bs->total_clusters = ctx->bs->dev->blockcnt / (ctx->bs->cluster_sz / ctx->bs->dev->blocklen); + ctx->bs->pages_per_cluster = ctx->bs->cluster_sz / SPDK_BS_PAGE_SIZE; + ctx->bs->md_start = ctx->super->md_start; + ctx->bs->md_len = ctx->super->md_len; + ctx->bs->super_blob = ctx->super->super_blob; + + /* Read the used pages mask */ + mask_size = ctx->super->used_page_mask_len * SPDK_BS_PAGE_SIZE; + ctx->mask = spdk_dma_zmalloc(mask_size, 0x1000, NULL); + if (!ctx->mask) { + spdk_dma_free(ctx->super); + _spdk_bs_free(ctx->bs); + free(ctx); + spdk_bs_sequence_finish(seq, -ENOMEM); + return; + } + + lba = _spdk_bs_page_to_lba(ctx->bs, ctx->super->used_page_mask_start); + lba_count = _spdk_bs_page_to_lba(ctx->bs, ctx->super->used_page_mask_len); + spdk_bs_sequence_read(seq, ctx->mask, lba, lba_count, + _spdk_bs_load_used_pages_cpl, ctx); +} + static void _spdk_bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) { struct spdk_bs_load_ctx *ctx = cb_arg; - uint64_t lba, lba_count, mask_size; if (ctx->super->version != SPDK_BS_VERSION) { spdk_dma_free(ctx->super); @@ -1520,30 +1550,12 @@ _spdk_bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) spdk_bs_sequence_finish(seq, -EILSEQ); return; } + ctx->super->clean = 0; - /* Parse the super block */ - ctx->bs->cluster_sz = ctx->super->cluster_size; - ctx->bs->total_clusters = ctx->bs->dev->blockcnt / (ctx->bs->cluster_sz / ctx->bs->dev->blocklen); - ctx->bs->pages_per_cluster = ctx->bs->cluster_sz / SPDK_BS_PAGE_SIZE; - ctx->bs->md_start = ctx->super->md_start; - ctx->bs->md_len = ctx->super->md_len; - ctx->bs->super_blob = ctx->super->super_blob; - - /* Read the used pages mask */ - mask_size = ctx->super->used_page_mask_len * SPDK_BS_PAGE_SIZE; - ctx->mask = spdk_dma_zmalloc(mask_size, 0x1000, NULL); - if (!ctx->mask) { - spdk_dma_free(ctx->super); - _spdk_bs_free(ctx->bs); - free(ctx); - spdk_bs_sequence_finish(seq, -ENOMEM); - return; - } - lba = _spdk_bs_page_to_lba(ctx->bs, ctx->super->used_page_mask_start); - lba_count = _spdk_bs_page_to_lba(ctx->bs, ctx->super->used_page_mask_len); - spdk_bs_sequence_read(seq, ctx->mask, lba, lba_count, - _spdk_bs_load_used_pages_cpl, ctx); + spdk_bs_sequence_write(seq, ctx->super, _spdk_bs_page_to_lba(ctx->bs, 0), + _spdk_bs_byte_to_lba(ctx->bs, sizeof(*ctx->super)), + _spdk_bs_load_write_super_cpl, ctx); } void diff --git a/test/unit/lib/blob/blob.c/blob_ut.c b/test/unit/lib/blob/blob.c/blob_ut.c index f80813c67..22211554b 100644 --- a/test/unit/lib/blob/blob.c/blob_ut.c +++ b/test/unit/lib/blob/blob.c/blob_ut.c @@ -849,6 +849,7 @@ bs_load(void) struct spdk_bs_dev *dev; spdk_blob_id blobid; struct spdk_blob *blob; + struct spdk_bs_super_block *super_blob; uint64_t length; int rc; const void *value; @@ -897,12 +898,17 @@ bs_load(void) g_blob = NULL; g_blobid = 0; + super_blob = (struct spdk_bs_super_block *)g_dev_buffer; + CU_ASSERT(super_blob->clean == 1); dev = init_dev(); /* Load an existing blob store */ spdk_bs_load(dev, bs_op_with_handle_complete, NULL); CU_ASSERT(g_bserrno == 0); SPDK_CU_ASSERT_FATAL(g_bs != NULL); + super_blob = (struct spdk_bs_super_block *)g_dev_buffer; + CU_ASSERT(super_blob->clean == 0); + spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); CU_ASSERT(g_bserrno == 0); CU_ASSERT(g_blob != NULL);