lib/blob: update pages array during blob load

When loading a blob and parsing its metadata,
the array of pages was not updated.
Serialization was unaffected, since the current pages
array is unused there.
Behavior was working correctly for first page,
but did not for any blob with more than one page.

Unfortunetly blob_persist_zero_pages() never zeroed out
the pages, neither blob_persist_zero_pages_cpl()
released the md pages.

Resulting in md pages being claimed even after blobs
deletion.

This patch now fills out the active pages array with
the appropriate page numbers from metadata.

Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: I6ff1f4fe95684119d283c2471fdbbea464da8151
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4504
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Tomasz Zawadzki 2020-10-02 05:01:25 -04:00
parent 34f84c5845
commit 63e257ed34
2 changed files with 47 additions and 0 deletions

View File

@ -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];

View File

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