lib/blob: add EXTENT descriptor to blobs
Similar to EXTENT_RLE, this descriptor holds LBA of clusters. Difference is that EXTENT is kept in separate md pages, and only single EXTENT will be updated on cluster allocation. This patch adds the EXTENT processing, which is not used until following patch. Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Change-Id: Ifbac23db7ca3e7c8c91cee01018f20071f0d5160 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/470014 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com>
This commit is contained in:
parent
0dfe80c82a
commit
f4e58993f7
@ -637,6 +637,53 @@ _spdk_blob_parse_page(const struct spdk_blob_md_page *page, struct spdk_blob *bl
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
} else if (desc->type == SPDK_MD_DESCRIPTOR_TYPE_EXTENT_PAGE) {
|
||||
struct spdk_blob_md_descriptor_extent_page *desc_extent;
|
||||
unsigned int i;
|
||||
unsigned int cluster_count = blob->active.num_clusters;
|
||||
|
||||
if (blob->extent_rle_found) {
|
||||
/* This means that Extent RLE is present in MD,
|
||||
* both should never be at the same time. */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
desc_extent = (struct spdk_blob_md_descriptor_extent_page *)desc;
|
||||
|
||||
if (desc_extent->length == 0 ||
|
||||
(desc_extent->length % sizeof(desc_extent->cluster_idx[0]) != 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < desc_extent->length / sizeof(desc_extent->cluster_idx[0]); i++) {
|
||||
if (desc_extent->cluster_idx[i] != 0) {
|
||||
if (!spdk_bit_array_get(blob->bs->used_clusters, desc_extent->cluster_idx[i])) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
cluster_count++;
|
||||
}
|
||||
|
||||
if (cluster_count == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
tmp = realloc(blob->active.clusters, cluster_count * sizeof(*blob->active.clusters));
|
||||
if (tmp == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
blob->active.clusters = tmp;
|
||||
blob->active.cluster_array_size = cluster_count;
|
||||
|
||||
for (i = 0; i < desc_extent->length / sizeof(desc_extent->cluster_idx[0]); i++) {
|
||||
if (desc_extent->cluster_idx[i] != 0) {
|
||||
blob->active.clusters[blob->active.num_clusters++] = _spdk_bs_cluster_to_lba(blob->bs,
|
||||
desc_extent->cluster_idx[i]);
|
||||
} else if (spdk_blob_is_thin_provisioned(blob)) {
|
||||
blob->active.clusters[blob->active.num_clusters++] = 0;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
} else if (desc->type == SPDK_MD_DESCRIPTOR_TYPE_XATTR) {
|
||||
int rc;
|
||||
|
||||
@ -3352,6 +3399,8 @@ _spdk_bs_load_replay_md_parse_page(const struct spdk_blob_md_page *page, struct
|
||||
if (cluster_count == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (desc->type == SPDK_MD_DESCRIPTOR_TYPE_EXTENT_PAGE) {
|
||||
/* Skip this item */
|
||||
} else if (desc->type == SPDK_MD_DESCRIPTOR_TYPE_XATTR) {
|
||||
/* Skip this item */
|
||||
} else if (desc->type == SPDK_MD_DESCRIPTOR_TYPE_XATTR_INTERNAL) {
|
||||
@ -3384,6 +3433,7 @@ static bool _spdk_bs_load_cur_md_page_valid(struct spdk_bs_load_ctx *ctx)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* First page of a sequence should match the blobid. */
|
||||
if (ctx->page->sequence_num == 0 &&
|
||||
_spdk_bs_page_to_blobid(ctx->cur_page) != ctx->page->id) {
|
||||
return false;
|
||||
@ -3788,6 +3838,21 @@ _spdk_bs_dump_print_md_page(struct spdk_bs_dump_ctx *ctx)
|
||||
fprintf(ctx->fp, " Length: %" PRIu32, desc_extent_rle->extents[i].length);
|
||||
fprintf(ctx->fp, "\n");
|
||||
}
|
||||
} else if (desc->type == SPDK_MD_DESCRIPTOR_TYPE_EXTENT_PAGE) {
|
||||
struct spdk_blob_md_descriptor_extent_page *desc_extent;
|
||||
unsigned int i;
|
||||
|
||||
desc_extent = (struct spdk_blob_md_descriptor_extent_page *)desc;
|
||||
|
||||
for (i = 0; i < desc_extent->length / sizeof(desc_extent->cluster_idx[0]); i++) {
|
||||
if (desc_extent->cluster_idx[i] != 0) {
|
||||
fprintf(ctx->fp, "Allocated Extent - Start: %" PRIu32,
|
||||
desc_extent->cluster_idx[i]);
|
||||
} else {
|
||||
fprintf(ctx->fp, "Unallocated Extent");
|
||||
}
|
||||
fprintf(ctx->fp, "\n");
|
||||
}
|
||||
} else if (desc->type == SPDK_MD_DESCRIPTOR_TYPE_XATTR) {
|
||||
struct spdk_blob_md_descriptor_xattr *desc_xattr;
|
||||
uint32_t i;
|
||||
|
@ -279,6 +279,11 @@ struct spdk_bs_md_mask {
|
||||
* are run-length encoded, non-zero values are unallocated pages.
|
||||
* It is part of serialized metadata chain for a blob. */
|
||||
#define SPDK_MD_DESCRIPTOR_TYPE_EXTENT_TABLE 5
|
||||
/* EXTENT_PAGE descriptor holds an array of LBAs that point to
|
||||
* beginning of allocated clusters. The array is run-length encoded,
|
||||
* with 0's being unallocated clusters. It is NOT part of
|
||||
* serialized metadata chain for a blob. */
|
||||
#define SPDK_MD_DESCRIPTOR_TYPE_EXTENT_PAGE 6
|
||||
|
||||
struct spdk_blob_md_descriptor_xattr {
|
||||
uint8_t type;
|
||||
@ -314,6 +319,14 @@ struct spdk_blob_md_descriptor_extent_table {
|
||||
} extent_page[0];
|
||||
};
|
||||
|
||||
struct spdk_blob_md_descriptor_extent_page {
|
||||
uint8_t type;
|
||||
uint32_t length;
|
||||
|
||||
/* TODO: add indicator for ranges of clusters in this EP */
|
||||
uint32_t cluster_idx[0];
|
||||
};
|
||||
|
||||
#define SPDK_BLOB_THIN_PROV (1ULL << 0)
|
||||
#define SPDK_BLOB_INTERNAL_XATTR (1ULL << 1)
|
||||
#define SPDK_BLOB_INVALID_FLAGS_MASK (SPDK_BLOB_THIN_PROV | SPDK_BLOB_INTERNAL_XATTR)
|
||||
|
Loading…
Reference in New Issue
Block a user