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 <piotr.pelplinski@intel.com>
Change-Id: I7be81009a99f09048bf23749c8f6ef5e9f7b3751

Reviewed-on: https://review.gerrithub.io/410884
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Maciej Szwed <maciej.szwed@intel.com>
This commit is contained in:
Piotr Pelplinski 2018-05-10 13:43:17 +02:00 committed by Daniel Verkamp
parent 88168dd8b8
commit bc8f2cd90f
3 changed files with 55 additions and 5 deletions

View File

@ -953,6 +953,8 @@ _spdk_blob_load(spdk_bs_sequence_t *seq, struct spdk_blob *blob,
struct spdk_blob_persist_ctx { struct spdk_blob_persist_ctx {
struct spdk_blob *blob; struct spdk_blob *blob;
struct spdk_bs_super_block *super;
struct spdk_blob_md_page *pages; struct spdk_blob_md_page *pages;
uint64_t idx; 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); _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 */ /* Write a blob to disk */
static void static void
_spdk_blob_persist(spdk_bs_sequence_t *seq, struct spdk_blob *blob, _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_fn = cb_fn;
ctx->cb_arg = cb_arg; 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 { 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 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; struct spdk_bs_load_ctx *ctx = cb_arg;
uint64_t lba, lba_count, mask_size; 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 */ /* Parse the super block */
ctx->bs->clean = 1;
ctx->bs->cluster_sz = ctx->super->cluster_size; 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->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->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. * using _spdk_bs_recover.
*/ */
ctx->super->clean = 0; ctx->super->clean = 0;
ctx->bs->clean = 0;
_spdk_bs_write_super(seq, ctx->bs, ctx->super, _spdk_bs_recover, ctx); _spdk_bs_write_super(seq, ctx->bs, ctx->super, _spdk_bs_recover, ctx);
} else { } else {
ctx->super->clean = 0; _spdk_bs_load_read_used_pages(seq, ctx);
_spdk_bs_write_super(seq, ctx->bs, ctx->super, _spdk_bs_load_write_super_cpl, ctx);
} }
} }

View File

@ -180,6 +180,8 @@ struct spdk_blob_store {
TAILQ_HEAD(, spdk_blob) blobs; TAILQ_HEAD(, spdk_blob) blobs;
TAILQ_HEAD(, spdk_blob_list) snapshots; TAILQ_HEAD(, spdk_blob_list) snapshots;
bool clean;
}; };
struct spdk_bs_channel { struct spdk_bs_channel {

View File

@ -1863,13 +1863,17 @@ bs_load(void)
SPDK_CU_ASSERT_FATAL(g_bs != NULL); SPDK_CU_ASSERT_FATAL(g_bs != NULL);
super_block = (struct spdk_bs_super_block *)g_dev_buffer; 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); spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == 0); CU_ASSERT(g_bserrno == 0);
CU_ASSERT(g_blob != NULL); CU_ASSERT(g_blob != NULL);
blob = g_blob; 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 */ /* Get the xattrs */
value = NULL; value = NULL;
rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);