From c33840b7e6e8d09f40a7c178bdb27d6a5e2374d8 Mon Sep 17 00:00:00 2001 From: Tomasz Zawadzki Date: Tue, 21 Jan 2020 12:14:19 -0500 Subject: [PATCH] lib/blob: add option to enable extent pages This is an additional option that can be passed when creating a blob. When opts->enable_extent_pages is set to false (current default), only EXTENT_RLE should be persisted on sync. During blob load, when EXTENT_RLE is present in md, blob->extent_rle_found is set to true. When opts->enable_extent_pages is set to true, only EXTENT_TABLE and EXTENT_PAGES should be persisted on sync. During blob load, when EXTENT_TABLE is present in md, blob->extent_table_found is set to true. It is possible to find neither EXTENT_* descriptor when loading a blob. This means that blob length is 0 and EXTENT_RLE was supposed to be used. Yet none were persisted due to lack of clusters. In such case blob->use_extent_table is set to true after finishing blob load. When parsing metadata ends, if extent_table_found is set - then support for extent_table is enabled. All other cases disable it. At this time path for Extent Pages is not implemented, so it should not be used. Later in the series, it will become the default path for serialization. Signed-off-by: Tomasz Zawadzki Change-Id: I2146da6130a0645e686ab02a3b5d2d86a7d35a1f Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479853 Reviewed-by: Jim Harris Reviewed-by: Paul Luse Reviewed-by: Ben Walker Tested-by: SPDK CI Jenkins --- include/spdk/blob.h | 3 +++ lib/blob/blobstore.c | 38 ++++++++++++++++++++++++++++++++++++-- lib/blob/blobstore.h | 3 +++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/include/spdk/blob.h b/include/spdk/blob.h index d5ddfee67..fbc2728ee 100644 --- a/include/spdk/blob.h +++ b/include/spdk/blob.h @@ -412,6 +412,9 @@ struct spdk_blob_opts { bool thin_provision; enum blob_clear_method clear_method; struct spdk_blob_xattr_opts xattrs; + + /** Enable separate extent pages in metadata */ + bool use_extent_table; }; /** diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index 18c6d6b54..bd4d511d9 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -167,6 +167,7 @@ spdk_blob_opts_init(struct spdk_blob_opts *opts) opts->thin_provision = false; opts->clear_method = BLOB_CLEAR_WITH_DEFAULT; _spdk_blob_xattrs_init(&opts->xattrs); + opts->use_extent_table = false; } void @@ -191,6 +192,8 @@ _spdk_blob_alloc(struct spdk_blob_store *bs, spdk_blob_id id) blob->parent_id = SPDK_BLOBID_INVALID; blob->state = SPDK_BLOB_STATE_DIRTY; + blob->extent_rle_found = false; + blob->extent_table_found = false; blob->active.num_pages = 1; blob->active.pages = calloc(1, sizeof(*blob->active.pages)); if (!blob->active.pages) { @@ -481,6 +484,13 @@ _spdk_blob_parse_page(const struct spdk_blob_md_page *page, struct spdk_blob *bl unsigned int i, j; unsigned int cluster_count = blob->active.num_clusters; + if (blob->extent_table_found) { + /* Extent Table already present in the md, + * both descriptors should never be at the same time. */ + return -EINVAL; + } + blob->extent_rle_found = true; + desc_extent_rle = (struct spdk_blob_md_descriptor_extent_rle *)desc; if (desc_extent_rle->length == 0 || @@ -887,8 +897,14 @@ _spdk_blob_serialize(const struct spdk_blob *blob, struct spdk_blob_md_page **pa return rc; } - /* Serialize extents */ - rc = _spdk_blob_serialize_extents_rle(blob, pages, cur_page, page_count, &buf, &remaining_sz); + if (blob->use_extent_table) { + /* Serialization as extent pages is not yet implemented */ + assert(false); + rc = -ENOSYS; + } else { + /* Serialize extents */ + rc = _spdk_blob_serialize_extents_rle(blob, pages, cur_page, page_count, &buf, &remaining_sz); + } return rc; } @@ -1036,6 +1052,19 @@ _spdk_blob_load_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) _spdk_blob_load_final(ctx, rc); return; } + + if (blob->extent_table_found == true) { + /* If EXTENT_TABLE was found, that means support for it should be enabled. */ + assert(blob->extent_rle_found == false); + blob->use_extent_table = true; + } else { + /* If EXTENT_RLE or no extent_* descriptor was found disable support + * for extent table. No extent_* descriptors means that blob has length of 0 + * and no extent_rle descriptors were persisted for it. + * EXTENT_TABLE if used, is always present in metadata regardless of length. */ + blob->use_extent_table = false; + } + ctx->seq = seq; /* Check the clear_method stored in metadata vs what may have been passed @@ -4398,6 +4427,9 @@ _spdk_bs_create_blob(struct spdk_blob_store *bs, spdk_blob_opts_init(&opts_default); opts = &opts_default; } + + blob->use_extent_table = opts->use_extent_table; + if (!internal_xattrs) { _spdk_blob_xattrs_init(&internal_xattrs_default); internal_xattrs = &internal_xattrs_default; @@ -4794,6 +4826,7 @@ _spdk_bs_snapshot_origblob_open_cpl(void *cb_arg, struct spdk_blob *_blob, int b * but do not allocate clusters */ opts.thin_provision = true; opts.num_clusters = spdk_blob_get_num_clusters(_blob); + opts.use_extent_table = _blob->use_extent_table; /* If there are any xattrs specified for snapshot, set them now */ if (ctx->xattrs) { @@ -4902,6 +4935,7 @@ _spdk_bs_clone_origblob_open_cpl(void *cb_arg, struct spdk_blob *_blob, int bser opts.thin_provision = true; opts.num_clusters = spdk_blob_get_num_clusters(_blob); + opts.use_extent_table = _blob->use_extent_table; if (ctx->xattrs) { memcpy(&opts.xattrs, ctx->xattrs, sizeof(*ctx->xattrs)); } diff --git a/lib/blob/blobstore.h b/lib/blob/blobstore.h index c45e7fcda..83f810634 100644 --- a/lib/blob/blobstore.h +++ b/lib/blob/blobstore.h @@ -150,6 +150,9 @@ struct spdk_blob { uint32_t frozen_refcnt; bool locked_operation_in_progress; enum blob_clear_method clear_method; + bool extent_rle_found; + bool extent_table_found; + bool use_extent_table; }; struct spdk_blob_store {