blobstore: make blob_persist_check_dirty separate from persist

This patch makes marking blobstore as dirty, separate from
persist process. Adding a context strucutre and new single
callback once completed.

It is being as part of refactor to allow marking blobstore
dirty when writing out extent page - see #2830.

Change-Id: Ie2e9cc32860697e0e747939842ab04f48fbff49b
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16328
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Tomasz Zawadzki 2023-01-17 14:26:42 +01:00
parent 3eb03cc7b6
commit acdfc03590

View File

@ -1588,8 +1588,6 @@ 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;
uint32_t next_extent_page;
struct spdk_blob_md_page *extent_page;
@ -1618,7 +1616,8 @@ bs_batch_clear_dev(struct spdk_blob_persist_ctx *ctx, spdk_bs_batch_t *batch, ui
}
}
static void blob_persist_check_dirty(struct spdk_blob_persist_ctx *ctx);
static void bs_mark_dirty(spdk_bs_sequence_t *seq, struct spdk_blob_store *bs,
spdk_bs_sequence_cpl cb_fn, void *cb_arg);
static void
blob_persist_complete_cb(void *arg)
@ -1633,6 +1632,8 @@ blob_persist_complete_cb(void *arg)
free(ctx);
}
static void blob_persist_start(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno);
static void
blob_persist_complete(spdk_bs_sequence_t *seq, struct spdk_blob_persist_ctx *ctx, int bserrno)
{
@ -1660,7 +1661,7 @@ blob_persist_complete(spdk_bs_sequence_t *seq, struct spdk_blob_persist_ctx *ctx
next_persist = TAILQ_FIRST(&blob->persists_to_complete);
blob->state = SPDK_BLOB_STATE_DIRTY;
blob_persist_check_dirty(next_persist);
bs_mark_dirty(seq, blob->bs, blob_persist_start, next_persist);
}
static void
@ -2207,11 +2208,16 @@ blob_persist_write_extent_pages(spdk_bs_sequence_t *seq, void *cb_arg, int bserr
}
static void
blob_persist_start(struct spdk_blob_persist_ctx *ctx)
blob_persist_start(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
{
spdk_bs_sequence_t *seq = ctx->seq;
struct spdk_blob_persist_ctx *ctx = cb_arg;
struct spdk_blob *blob = ctx->blob;
if (bserrno != 0) {
blob_persist_complete(seq, ctx, bserrno);
return;
}
if (blob->active.num_pages == 0) {
/* This is the signal that the blob should be deleted.
* Immediately jump to the clean up routine. */
@ -2239,21 +2245,26 @@ blob_persist_start(struct spdk_blob_persist_ctx *ctx)
blob_persist_write_extent_pages(seq, ctx, 0);
}
struct spdk_bs_mark_dirty {
struct spdk_blob_store *bs;
struct spdk_bs_super_block *super;
spdk_bs_sequence_cpl cb_fn;
void *cb_arg;
};
static void
blob_persist_dirty_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
bs_mark_dirty_write_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
{
struct spdk_blob_persist_ctx *ctx = cb_arg;
struct spdk_bs_mark_dirty *ctx = cb_arg;
spdk_free(ctx->super);
if (bserrno != 0) {
blob_persist_complete(seq, ctx, bserrno);
return;
if (bserrno == 0) {
ctx->bs->clean = 0;
}
ctx->blob->bs->clean = 0;
ctx->cb_fn(seq, ctx->cb_arg, bserrno);
blob_persist_start(ctx);
spdk_free(ctx->super);
free(ctx);
}
static void bs_write_super(spdk_bs_sequence_t *seq, struct spdk_blob_store *bs,
@ -2261,41 +2272,55 @@ static void bs_write_super(spdk_bs_sequence_t *seq, struct spdk_blob_store *bs,
static void
blob_persist_dirty(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
bs_mark_dirty_write(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
{
struct spdk_blob_persist_ctx *ctx = cb_arg;
struct spdk_bs_mark_dirty *ctx = cb_arg;
if (bserrno != 0) {
spdk_free(ctx->super);
blob_persist_complete(seq, ctx, bserrno);
bs_mark_dirty_write_cpl(seq, ctx, bserrno);
return;
}
ctx->super->clean = 0;
if (ctx->super->size == 0) {
ctx->super->size = ctx->blob->bs->dev->blockcnt * ctx->blob->bs->dev->blocklen;
ctx->super->size = ctx->bs->dev->blockcnt * ctx->bs->dev->blocklen;
}
bs_write_super(seq, ctx->blob->bs, ctx->super, blob_persist_dirty_cpl, ctx);
bs_write_super(seq, ctx->bs, ctx->super, bs_mark_dirty_write_cpl, ctx);
}
static void
blob_persist_check_dirty(struct spdk_blob_persist_ctx *ctx)
bs_mark_dirty(spdk_bs_sequence_t *seq, struct spdk_blob_store *bs,
spdk_bs_sequence_cpl cb_fn, void *cb_arg)
{
if (ctx->blob->bs->clean) {
ctx->super = spdk_zmalloc(sizeof(*ctx->super), 0x1000, NULL,
SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA);
if (!ctx->super) {
blob_persist_complete(ctx->seq, ctx, -ENOMEM);
return;
}
struct spdk_bs_mark_dirty *ctx;
bs_sequence_read_dev(ctx->seq, ctx->super, bs_page_to_lba(ctx->blob->bs, 0),
bs_byte_to_lba(ctx->blob->bs, sizeof(*ctx->super)),
blob_persist_dirty, ctx);
} else {
blob_persist_start(ctx);
/* Blobstore is already marked dirty */
if (bs->clean == 0) {
cb_fn(seq, cb_arg, 0);
return;
}
ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
cb_fn(seq, cb_arg, -ENOMEM);
return;
}
ctx->bs = bs;
ctx->cb_fn = cb_fn;
ctx->cb_arg = cb_arg;
ctx->super = spdk_zmalloc(sizeof(*ctx->super), 0x1000, NULL,
SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA);
if (!ctx->super) {
free(ctx);
cb_fn(seq, cb_arg, -ENOMEM);
return;
}
bs_sequence_read_dev(seq, ctx->super, bs_page_to_lba(bs, 0),
bs_byte_to_lba(bs, sizeof(*ctx->super)),
bs_mark_dirty_write, ctx);
}
/* Write a blob to disk */
@ -2330,7 +2355,7 @@ blob_persist(spdk_bs_sequence_t *seq, struct spdk_blob *blob,
}
TAILQ_INSERT_HEAD(&blob->persists_to_complete, ctx, link);
blob_persist_check_dirty(ctx);
bs_mark_dirty(seq, blob->bs, blob_persist_start, ctx);
}
struct spdk_blob_copy_cluster_ctx {