blobstore: store usable number of clusters in blobstore structure

At the moment there was no way to a user of blobstore api to know,
how many clusters are availible to him. Total_clusters describes
number of clusters for metadata and user data.

New field added total_data_clusters, keeping number of clusters
that can be used to create blobs - meaning just user data.

Signed-off-by: Maciej Szwed <maciej.szwed@intel.com>
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: I60555217644557410844f74628375a6b46fd2ac7
Reviewed-on: https://review.gerrithub.io/385633
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Tomasz Zawadzki 2017-11-08 14:41:37 +01:00 committed by Jim Harris
parent 973a27d08c
commit 5eb52b951c
4 changed files with 91 additions and 0 deletions

View File

@ -196,6 +196,9 @@ uint64_t spdk_bs_get_page_size(struct spdk_blob_store *bs);
/* Get the number of free clusters. */
uint64_t spdk_bs_free_cluster_count(struct spdk_blob_store *bs);
/* Get the total number of clusters accessible by user. */
uint64_t spdk_bs_total_data_cluster_count(struct spdk_blob_store *bs);
/* Register the current thread as the metadata thread. All functions beginning with
* the prefix "spdk_bs_md" must be called only from this thread.
*/

View File

@ -1926,6 +1926,8 @@ _spdk_bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
ctx->bs->pages_per_cluster = ctx->bs->cluster_sz / SPDK_BS_PAGE_SIZE;
ctx->bs->md_start = ctx->super->md_start;
ctx->bs->md_len = ctx->super->md_len;
ctx->bs->total_data_clusters = ctx->bs->total_clusters - divide_round_up(
ctx->bs->md_start + ctx->bs->md_len, ctx->bs->pages_per_cluster);
ctx->bs->super_blob = ctx->super->super_blob;
memcpy(&ctx->bs->bstype, &ctx->super->bstype, sizeof(ctx->super->bstype));
@ -2169,6 +2171,8 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
_spdk_bs_claim_cluster(bs, i);
}
bs->total_data_clusters = bs->num_free_clusters;
cpl.type = SPDK_BS_CPL_TYPE_BS_HANDLE;
cpl.u.bs_handle.cb_fn = cb_fn;
cpl.u.bs_handle.cb_arg = cb_arg;
@ -2404,6 +2408,12 @@ spdk_bs_free_cluster_count(struct spdk_blob_store *bs)
return bs->num_free_clusters;
}
uint64_t
spdk_bs_total_data_cluster_count(struct spdk_blob_store *bs)
{
return bs->total_data_clusters;
}
int spdk_bs_register_md_thread(struct spdk_blob_store *bs)
{
bs->md_target.md_channel = spdk_get_io_channel(&bs->md_target);

View File

@ -154,6 +154,7 @@ struct spdk_blob_store {
uint32_t cluster_sz;
uint64_t total_clusters;
uint64_t total_data_clusters;
uint64_t num_free_clusters;
uint32_t pages_per_cluster;

View File

@ -1234,6 +1234,82 @@ bs_cluster_sz(void)
g_bs = NULL;
}
/*
* Create a blobstore, reload it and ensure total usable cluster count
* stays the same.
*/
static void
bs_usable_clusters(void)
{
struct spdk_bs_dev *dev;
struct spdk_bs_opts opts;
uint32_t clusters;
int i, rc;
/* Init blobstore */
dev = init_dev();
spdk_bs_opts_init(&opts);
spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == 0);
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
clusters = spdk_bs_total_data_cluster_count(g_bs);
/* Unload the blob store */
spdk_bs_unload(g_bs, bs_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
g_bs = NULL;
dev = init_dev();
/* Load an existing blob store */
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == 0);
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
/* Create and resize blobs to make sure that useable cluster count won't change */
for (i = 0; i < 4; i++) {
g_bserrno = -1;
g_blobid = SPDK_BLOBID_INVALID;
spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
g_bserrno = -1;
g_blob = NULL;
spdk_bs_md_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(g_blob != NULL);
rc = spdk_bs_md_resize_blob(g_blob, 10);
CU_ASSERT(rc == 0);
g_bserrno = -1;
spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
}
/* Reload the blob store to make sure that nothing changed */
spdk_bs_unload(g_bs, bs_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
g_bs = NULL;
dev = init_dev();
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == 0);
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
spdk_bs_unload(g_bs, bs_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
g_bs = NULL;
}
/*
* Test resizing of the metadata blob. This requires creating enough blobs
* so that one cluster is not enough to fit the metadata for those blobs.
@ -1845,6 +1921,7 @@ int main(int argc, char **argv)
CU_add_test(suite, "bs_load", bs_load) == NULL ||
CU_add_test(suite, "bs_unload", bs_unload) == NULL ||
CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL ||
CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
CU_add_test(suite, "bs_destroy", bs_destroy) == NULL ||
CU_add_test(suite, "bs_type", bs_type) == NULL ||