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 <tomasz.zawadzki@intel.com>
Change-Id: I2146da6130a0645e686ab02a3b5d2d86a7d35a1f
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479853
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Tomasz Zawadzki 2020-01-21 12:14:19 -05:00
parent 7ef33c86b8
commit c33840b7e6
3 changed files with 42 additions and 2 deletions

View File

@ -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;
};
/**

View File

@ -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));
}

View File

@ -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 {