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 <cunyin.chang@intel.com>
Reviewed-on: https://review.gerrithub.io/376276
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
This commit is contained in:
Cunyin Chang 2017-08-30 11:08:18 +08:00 committed by Daniel Verkamp
parent 26a40ff914
commit e87808c4fb
2 changed files with 41 additions and 23 deletions

View File

@ -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

View File

@ -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);