From 6fc44a7aeaf241eef1997f4da130d3069b4ff106 Mon Sep 17 00:00:00 2001 From: Tomasz Zawadzki Date: Fri, 13 Jul 2018 03:47:20 -0400 Subject: [PATCH] blob: fix unallocated clusters to run-length encode Before this patch when serializing extents, unallocated clusters were treated as separate lba. This caused metadata to grow without need. Change-Id: I5d66466dda5f5e6d4d53f4ed5bd0bac18c74be96 Signed-off-by: Tomasz Zawadzki Reviewed-on: https://review.gerrithub.io/419180 Chandler-Test-Pool: SPDK Automated Test System Tested-by: SPDK CI Jenkins Reviewed-by: Maciej Szwed Reviewed-by: Ben Walker Reviewed-by: Shuhei Matsumoto --- lib/blob/blobstore.c | 11 ++++++++--- test/unit/lib/blob/blob.c/blob_ut.c | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index 80101b112..c86031b17 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -473,9 +473,11 @@ _spdk_blob_parse_page(const struct spdk_blob_md_page *page, struct spdk_blob *bl for (i = 0; i < desc_extent->length / sizeof(desc_extent->extents[0]); i++) { for (j = 0; j < desc_extent->extents[i].length; j++) { - if (!spdk_bit_array_get(blob->bs->used_clusters, - desc_extent->extents[i].cluster_idx + j)) { - return -EINVAL; + if (desc_extent->extents[i].cluster_idx != 0) { + if (!spdk_bit_array_get(blob->bs->used_clusters, + desc_extent->extents[i].cluster_idx + j)) { + return -EINVAL; + } } cluster_count++; } @@ -686,6 +688,9 @@ _spdk_blob_serialize_extent(const struct spdk_blob *blob, if ((lba + lba_count) == blob->active.clusters[i]) { lba_count += lba_per_cluster; continue; + } else if (lba == 0 && blob->active.clusters[i] == 0) { + lba_count += lba_per_cluster; + continue; } desc->extents[extent_idx].cluster_idx = lba / lba_per_cluster; desc->extents[extent_idx].length = lba_count / lba_per_cluster; diff --git a/test/unit/lib/blob/blob.c/blob_ut.c b/test/unit/lib/blob/blob.c/blob_ut.c index b8fa90a6f..ea3fa45a3 100644 --- a/test/unit/lib/blob/blob.c/blob_ut.c +++ b/test/unit/lib/blob/blob.c/blob_ut.c @@ -3558,6 +3558,24 @@ blob_thin_prov_alloc(void) CU_ASSERT(blob->active.num_clusters == 5); CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); + /* Grow it to 1TB - still unallocated */ + spdk_blob_resize(blob, 262144, blob_op_complete, NULL); + CU_ASSERT(g_bserrno == 0); + CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); + CU_ASSERT(blob->active.num_clusters == 262144); + CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); + + spdk_blob_sync_md(blob, blob_op_complete, NULL); + CU_ASSERT(g_bserrno == 0); + /* Sync must not change anything */ + CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); + CU_ASSERT(blob->active.num_clusters == 262144); + CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); + /* Since clusters are not allocated, + * number of metadata pages is expected to be minimal. + */ + CU_ASSERT(blob->active.num_pages == 1); + /* Shrink the blob to 3 clusters - still unallocated */ spdk_blob_resize(blob, 3, blob_op_complete, NULL); CU_ASSERT(g_bserrno == 0);