From bc8f2cd90f4dd0ab5eeb0a1ce3241f360e8525fb Mon Sep 17 00:00:00 2001 From: Piotr Pelplinski Date: Thu, 10 May 2018 13:43:17 +0200 Subject: [PATCH] blobstore: Change behaviour of dirty bit The patch disables writing dirty bit during blobstore loading. Instead, dirty bit is written prior to the first metadata update. Signed-off-by: Piotr Pelplinski Change-Id: I7be81009a99f09048bf23749c8f6ef5e9f7b3751 Reviewed-on: https://review.gerrithub.io/410884 Tested-by: SPDK Automated Test System Reviewed-by: Ben Walker Reviewed-by: Daniel Verkamp Reviewed-by: Shuhei Matsumoto Reviewed-by: Maciej Szwed --- lib/blob/blobstore.c | 52 ++++++++++++++++++++++++++--- lib/blob/blobstore.h | 2 ++ test/unit/lib/blob/blob.c/blob_ut.c | 6 +++- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index a946cc762..3835ce222 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -953,6 +953,8 @@ _spdk_blob_load(spdk_bs_sequence_t *seq, struct spdk_blob *blob, struct spdk_blob_persist_ctx { struct spdk_blob *blob; + struct spdk_bs_super_block *super; + struct spdk_blob_md_page *pages; uint64_t idx; @@ -1341,6 +1343,34 @@ _spdk_blob_persist_start(struct spdk_blob_persist_ctx *ctx) _spdk_blob_persist_write_page_chain(seq, ctx, 0); } +static void +_spdk_blob_persist_dirty_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) +{ + struct spdk_blob_persist_ctx *ctx = cb_arg; + + ctx->blob->bs->clean = 0; + + spdk_dma_free(ctx->super); + + _spdk_blob_persist_start(ctx); +} + +static void +_spdk_bs_write_super(spdk_bs_sequence_t *seq, struct spdk_blob_store *bs, + struct spdk_bs_super_block *super, spdk_bs_sequence_cpl cb_fn, void *cb_arg); + + +static void +_spdk_blob_persist_dirty(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) +{ + struct spdk_blob_persist_ctx *ctx = cb_arg; + + ctx->super->clean = 0; + + _spdk_bs_write_super(seq, ctx->blob->bs, ctx->super, _spdk_blob_persist_dirty_cpl, ctx); +} + + /* Write a blob to disk */ static void _spdk_blob_persist(spdk_bs_sequence_t *seq, struct spdk_blob *blob, @@ -1365,7 +1395,20 @@ _spdk_blob_persist(spdk_bs_sequence_t *seq, struct spdk_blob *blob, ctx->cb_fn = cb_fn; ctx->cb_arg = cb_arg; - _spdk_blob_persist_start(ctx); + if (blob->bs->clean) { + ctx->super = spdk_dma_zmalloc(sizeof(*ctx->super), 0x1000, NULL); + if (!ctx->super) { + cb_fn(seq, cb_arg, -ENOMEM); + free(ctx); + return; + } + + spdk_bs_sequence_read_dev(seq, ctx->super, _spdk_bs_page_to_lba(blob->bs, 0), + _spdk_bs_byte_to_lba(blob->bs, sizeof(*ctx->super)), + _spdk_blob_persist_dirty, ctx); + } else { + _spdk_blob_persist_start(ctx); + } } struct spdk_blob_copy_cluster_ctx { @@ -2618,7 +2661,7 @@ _spdk_bs_load_used_pages_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) } static void -_spdk_bs_load_write_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) +_spdk_bs_load_read_used_pages(spdk_bs_sequence_t *seq, void *cb_arg) { struct spdk_bs_load_ctx *ctx = cb_arg; uint64_t lba, lba_count, mask_size; @@ -2906,6 +2949,7 @@ _spdk_bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) } /* Parse the super block */ + ctx->bs->clean = 1; 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; @@ -2925,10 +2969,10 @@ _spdk_bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) * using _spdk_bs_recover. */ ctx->super->clean = 0; + ctx->bs->clean = 0; _spdk_bs_write_super(seq, ctx->bs, ctx->super, _spdk_bs_recover, ctx); } else { - ctx->super->clean = 0; - _spdk_bs_write_super(seq, ctx->bs, ctx->super, _spdk_bs_load_write_super_cpl, ctx); + _spdk_bs_load_read_used_pages(seq, ctx); } } diff --git a/lib/blob/blobstore.h b/lib/blob/blobstore.h index bd399f1ce..633c4a049 100644 --- a/lib/blob/blobstore.h +++ b/lib/blob/blobstore.h @@ -180,6 +180,8 @@ struct spdk_blob_store { TAILQ_HEAD(, spdk_blob) blobs; TAILQ_HEAD(, spdk_blob_list) snapshots; + + bool clean; }; struct spdk_bs_channel { diff --git a/test/unit/lib/blob/blob.c/blob_ut.c b/test/unit/lib/blob/blob.c/blob_ut.c index 27bc9b03e..38cc819dd 100644 --- a/test/unit/lib/blob/blob.c/blob_ut.c +++ b/test/unit/lib/blob/blob.c/blob_ut.c @@ -1863,13 +1863,17 @@ bs_load(void) SPDK_CU_ASSERT_FATAL(g_bs != NULL); super_block = (struct spdk_bs_super_block *)g_dev_buffer; - CU_ASSERT(super_block->clean == 0); + CU_ASSERT(super_block->clean == 1); spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); CU_ASSERT(g_bserrno == 0); CU_ASSERT(g_blob != NULL); blob = g_blob; + /* Verify that blobstore is marked dirty after first metadata sync */ + spdk_blob_sync_md(blob, blob_op_complete, NULL); + CU_ASSERT(super_block->clean == 1); + /* Get the xattrs */ value = NULL; rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);