diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index 0afd4919d..9c063fc1b 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -766,6 +766,7 @@ blob_parse(const struct spdk_blob_md_page *pages, uint32_t page_count, const struct spdk_blob_md_page *page; uint32_t i; int rc; + void *tmp; assert(page_count > 0); assert(pages[0].sequence_num == 0); @@ -782,6 +783,20 @@ blob_parse(const struct spdk_blob_md_page *pages, uint32_t page_count, return -ENOENT; } + tmp = realloc(blob->active.pages, page_count * sizeof(*blob->active.pages)); + if (!tmp) { + return -ENOMEM; + } + blob->active.pages = tmp; + + blob->active.pages[0] = pages[0].id; + + for (i = 1; i < page_count; i++) { + assert(spdk_bit_array_get(blob->bs->used_md_pages, pages[i - 1].next)); + blob->active.pages[i] = pages[i - 1].next; + } + blob->active.num_pages = page_count; + for (i = 0; i < page_count; i++) { page = &pages[i]; diff --git a/test/unit/lib/blob/blob.c/blob_ut.c b/test/unit/lib/blob/blob.c/blob_ut.c index 21a39543c..dfcf2a3c2 100644 --- a/test/unit/lib/blob/blob.c/blob_ut.c +++ b/test/unit/lib/blob/blob.c/blob_ut.c @@ -2115,6 +2115,37 @@ blob_xattr(void) CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); } +static void +blob_parse_md(void) +{ + struct spdk_blob_store *bs = g_bs; + struct spdk_blob *blob; + int rc; + uint32_t used_pages; + size_t xattr_length; + char *xattr; + + used_pages = spdk_bit_array_count_set(bs->used_md_pages); + blob = ut_blob_create_and_open(bs, NULL); + + /* Create large extent to force more than 1 page of metadata. */ + xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) - + strlen("large_xattr"); + xattr = calloc(xattr_length, sizeof(char)); + SPDK_CU_ASSERT_FATAL(xattr != NULL); + rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); + free(xattr); + SPDK_CU_ASSERT_FATAL(rc == 0); + + spdk_blob_sync_md(blob, blob_op_complete, NULL); + poll_threads(); + + /* Delete the blob and verify that number of pages returned to before its creation. */ + SPDK_CU_ASSERT_FATAL(used_pages != spdk_bit_array_count_set(bs->used_md_pages)); + ut_blob_close_and_delete(bs, blob); + SPDK_CU_ASSERT_FATAL(used_pages == spdk_bit_array_count_set(bs->used_md_pages)); +} + static void bs_load(void) { @@ -6699,6 +6730,7 @@ int main(int argc, char **argv) CU_ADD_TEST(suite_bs, blob_unmap); CU_ADD_TEST(suite_bs, blob_iter); CU_ADD_TEST(suite_blob, blob_xattr); + CU_ADD_TEST(suite_bs, blob_parse_md); CU_ADD_TEST(suite, bs_load); CU_ADD_TEST(suite_bs, bs_load_pending_removal); CU_ADD_TEST(suite, bs_load_custom_cluster_size);