Commit f4e58993 authored by Tomasz Zawadzki's avatar Tomasz Zawadzki
Browse files

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: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: Ifbac23db7ca3e7c8c91cee01018f20071f0d5160
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/470014


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
parent 0dfe80c8
Loading
Loading
Loading
Loading
+65 −0
Original line number Diff line number Diff line
@@ -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;
+13 −0
Original line number Diff line number Diff line
@@ -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)