lib/blob: write out extent pages before persisting metadata
Add new serialization of changed extent pages before persisting md. Iterate over active extent pages (not array !). When they are allocated but not yet present on disk - write them out. All extent pages in clean mutable data are assumed to be written out already. So there are two cases here: 1) Active mutable array is larger than clean All allocated extent pages should be written out. 2) Cluster allocation created new extent page Blob has to be thin provisioned and persist was called as part of cluster allocation. New extent page needs to be written out and EXTENT_TABLE allocated. Iteration is done over num_extent_pages instead of extent_pages_array_size, to prevent writting out too many extent pages when size of blob was made smaller. The two values come back in sync at the end of persist either way. Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Change-Id: I780819fd7f3c44e4cf5d71c188c642536d3cc320 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479851 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com>
This commit is contained in:
parent
2bccb7c9b4
commit
d1f863ca57
@ -1395,6 +1395,8 @@ struct spdk_blob_persist_ctx {
|
||||
struct spdk_bs_super_block *super;
|
||||
|
||||
struct spdk_blob_md_page *pages;
|
||||
uint32_t next_extent_page;
|
||||
struct spdk_blob_md_page *extent_page;
|
||||
|
||||
spdk_bs_sequence_t *seq;
|
||||
spdk_bs_sequence_cpl cb_fn;
|
||||
@ -1827,6 +1829,68 @@ _spdk_blob_persist_generate_new_md(struct spdk_blob_persist_ctx *ctx)
|
||||
_spdk_blob_persist_write_page_chain(seq, ctx, 0);
|
||||
}
|
||||
|
||||
static void _spdk_blob_persist_write_extent_pages(spdk_bs_sequence_t *seq, void *cb_arg,
|
||||
int bserrno);
|
||||
|
||||
static void
|
||||
_spdk_blob_persist_write_extent_page(uint32_t extent, uint64_t cluster_num,
|
||||
struct spdk_blob_persist_ctx *ctx)
|
||||
{
|
||||
spdk_bs_sequence_t *seq = ctx->seq;
|
||||
uint32_t page_count = 0;
|
||||
struct spdk_blob *blob = ctx->blob;
|
||||
int rc;
|
||||
|
||||
rc = _spdk_blob_serialize_add_page(blob, &ctx->extent_page, &page_count, &ctx->extent_page);
|
||||
if (rc < 0) {
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
_spdk_blob_serialize_extent_page(blob, cluster_num, ctx->extent_page);
|
||||
|
||||
ctx->extent_page->crc = _spdk_blob_md_page_calc_crc(ctx->extent_page);
|
||||
|
||||
spdk_bs_sequence_write_dev(seq, ctx->extent_page, _spdk_bs_md_page_to_lba(blob->bs, extent),
|
||||
_spdk_bs_byte_to_lba(blob->bs, SPDK_BS_PAGE_SIZE),
|
||||
_spdk_blob_persist_write_extent_pages, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_blob_persist_write_extent_pages(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
|
||||
{
|
||||
struct spdk_blob_persist_ctx *ctx = cb_arg;
|
||||
struct spdk_blob *blob = ctx->blob;
|
||||
size_t i;
|
||||
uint32_t extent_page_id;
|
||||
|
||||
if (ctx->extent_page != NULL) {
|
||||
spdk_free(ctx->extent_page);
|
||||
ctx->extent_page = NULL;
|
||||
}
|
||||
|
||||
/* Only write out changed extent pages */
|
||||
for (i = ctx->next_extent_page; i < blob->active.num_extent_pages; i++) {
|
||||
extent_page_id = blob->active.extent_pages[i];
|
||||
if (extent_page_id == 0) {
|
||||
/* No Extent Page to persist */
|
||||
assert(spdk_blob_is_thin_provisioned(blob));
|
||||
continue;
|
||||
}
|
||||
/* Writing out new extent page for the first time. Either active extent pages is larger
|
||||
* than clean extent pages or there was no extent page assigned due to thin provisioning. */
|
||||
if (i >= blob->clean.extent_pages_array_size || blob->clean.extent_pages[i] == 0) {
|
||||
assert(spdk_bit_array_get(blob->bs->used_md_pages, extent_page_id));
|
||||
ctx->next_extent_page = i + 1;
|
||||
_spdk_blob_persist_write_extent_page(extent_page_id, i * SPDK_EXTENTS_PER_EP, ctx);
|
||||
return;
|
||||
}
|
||||
assert(blob->clean.extent_pages[i] != 0);
|
||||
}
|
||||
|
||||
_spdk_blob_persist_generate_new_md(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_blob_persist_start(struct spdk_blob_persist_ctx *ctx)
|
||||
{
|
||||
@ -1843,7 +1907,7 @@ _spdk_blob_persist_start(struct spdk_blob_persist_ctx *ctx)
|
||||
|
||||
}
|
||||
|
||||
_spdk_blob_persist_generate_new_md(ctx);
|
||||
_spdk_blob_persist_write_extent_pages(seq, ctx, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1900,6 +1964,7 @@ _spdk_blob_persist(spdk_bs_sequence_t *seq, struct spdk_blob *blob,
|
||||
ctx->seq = seq;
|
||||
ctx->cb_fn = cb_fn;
|
||||
ctx->cb_arg = cb_arg;
|
||||
ctx->next_extent_page = 0;
|
||||
|
||||
if (blob->bs->clean) {
|
||||
ctx->super = spdk_zmalloc(sizeof(*ctx->super), 0x1000, NULL,
|
||||
|
Loading…
Reference in New Issue
Block a user