Commit 5eb52b95 authored by Tomasz Zawadzki's avatar Tomasz Zawadzki Committed by Jim Harris
Browse files

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: default avatarMaciej Szwed <maciej.szwed@intel.com>
Signed-off-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: I60555217644557410844f74628375a6b46fd2ac7
Reviewed-on: https://review.gerrithub.io/385633


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 973a27d0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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.
 */
+10 −0
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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;

+77 −0
Original line number Diff line number Diff line
@@ -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 ||