Commit 7c56c393 authored by Jim Harris's avatar Jim Harris
Browse files

bit_array: return UINT32_MAX if no cleared bits found



spdk_bit_array_find_first_set() returns UINT32_MAX if no
set bits are found.  But spdk_bit_array_find_first_clear()
would return the size of the bit array instead in this case.
(Note: the comments say size of the bit array + 1 which was
incorrect)

So this patch makes spdk_bit_array_find_first_clear()
consistent with spdk_bit_array_find_first_set() and returns
UINT32_MAX if no cleared bit is found.

Signed-off-by: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: I44c1e674149f8c2e87122800d5db45a2851f0bef

Reviewed-on: https://review.gerrithub.io/428225


Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarZiye Yang <optimistyzy@gmail.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
parent 76c5ec4c
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -151,9 +151,7 @@ uint32_t spdk_bit_array_find_first_set(const struct spdk_bit_array *ba, uint32_t
 * \param start_bit_index The bit index from which to start searching (0 to start
 * from the beginning of the array).
 *
 * \return the index of the first cleared bit. Bits beyond the current size of
 * the array are implicitly cleared, so if all bits within the current size are
 * set, this function will return the current number of bits + 1.
 * \return the index of the first cleared bit. If no bits are cleared, returns UINT32_MAX.
 */
uint32_t spdk_bit_array_find_first_clear(const struct spdk_bit_array *ba, uint32_t start_bit_index);

+5 −5
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ _spdk_bs_allocate_cluster(struct spdk_blob *blob, uint32_t cluster_num,
	pthread_mutex_lock(&blob->bs->used_clusters_mutex);
	*lowest_free_cluster = spdk_bit_array_find_first_clear(blob->bs->used_clusters,
			       *lowest_free_cluster);
	if (*lowest_free_cluster >= blob->bs->total_clusters) {
	if (*lowest_free_cluster == UINT32_MAX) {
		/* No more free clusters. Cannot satisfy the request */
		pthread_mutex_unlock(&blob->bs->used_clusters_mutex);
		return -ENOSPC;
@@ -1338,7 +1338,7 @@ _spdk_blob_resize(struct spdk_blob *blob, uint64_t sz)
		lfc = 0;
		for (i = num_clusters; i < sz; i++) {
			lfc = spdk_bit_array_find_first_clear(bs->used_clusters, lfc);
			if (lfc >= bs->total_clusters) {
			if (lfc == UINT32_MAX) {
				/* No more free clusters. Cannot satisfy the request */
				return -ENOSPC;
			}
@@ -1421,7 +1421,7 @@ _spdk_blob_persist_start(struct spdk_blob_persist_ctx *ctx)
	/* Note that this loop starts at one. The first page location is fixed by the blobid. */
	for (i = 1; i < blob->active.num_pages; i++) {
		page_num = spdk_bit_array_find_first_clear(bs->used_md_pages, page_num);
		if (page_num >= spdk_bit_array_capacity(bs->used_md_pages)) {
		if (page_num == UINT32_MAX) {
			_spdk_blob_persist_complete(seq, ctx, -ENOMEM);
			return;
		}
@@ -4106,7 +4106,7 @@ _spdk_bs_create_blob(struct spdk_blob_store *bs,
	assert(spdk_get_thread() == bs->md_thread);

	page_idx = spdk_bit_array_find_first_clear(bs->used_md_pages, 0);
	if (page_idx >= spdk_bit_array_capacity(bs->used_md_pages)) {
	if (page_idx == UINT32_MAX) {
		cb_fn(cb_arg, 0, -ENOMEM);
		return;
	}
@@ -4780,7 +4780,7 @@ _spdk_bs_inflate_blob_open_cpl(void *cb_arg, struct spdk_blob *_blob, int bserrn
	for (i = 0; i < _blob->active.num_clusters; i++) {
		if (_spdk_bs_cluster_needs_allocation(_blob, i, ctx->allocate_all)) {
			lfc = spdk_bit_array_find_first_clear(_blob->bs->used_clusters, lfc);
			if (lfc >= _blob->bs->total_clusters) {
			if (lfc == UINT32_MAX) {
				/* No more free clusters. Cannot satisfy the request */
				_spdk_bs_clone_snapshot_origblob_cleanup(ctx, -ENOSPC);
				return;
+18 −2
Original line number Diff line number Diff line
@@ -97,7 +97,11 @@ spdk_bit_array_resize(struct spdk_bit_array **bap, uint32_t num_bits)
	uint32_t old_word_count, new_word_count;
	size_t new_size;

	if (!bap) {
	/*
	 * Max number of bits allowed is UINT32_MAX - 1, because we use UINT32_MAX to denote
	 * when a set or cleared bit cannot be found.
	 */
	if (!bap || num_bits == UINT32_MAX) {
		return -EINVAL;
	}

@@ -269,7 +273,19 @@ spdk_bit_array_find_first_set(const struct spdk_bit_array *ba, uint32_t start_bi
uint32_t
spdk_bit_array_find_first_clear(const struct spdk_bit_array *ba, uint32_t start_bit_index)
{
	return _spdk_bit_array_find_first(ba, start_bit_index, SPDK_BIT_ARRAY_WORD_C(-1));
	uint32_t bit_index;

	bit_index = _spdk_bit_array_find_first(ba, start_bit_index, SPDK_BIT_ARRAY_WORD_C(-1));

	/*
	 * If we ran off the end of the array and found the 0 bit in the extra word,
	 * return UINT32_MAX to indicate no actual 0 bits were found.
	 */
	if (bit_index >= ba->bit_count) {
		bit_index = UINT32_MAX;
	}

	return bit_index;
}

uint32_t
+4 −4
Original line number Diff line number Diff line
@@ -133,10 +133,10 @@ test_find(void)
	/* Verify that find_first_set and find_first_clear work for each starting position */
	for (i = 0; i < 256; i++) {
		CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == i);
		CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == 256);
		CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == UINT32_MAX);
	}
	CU_ASSERT(spdk_bit_array_find_first_set(ba, 256) == UINT32_MAX);
	CU_ASSERT(spdk_bit_array_find_first_clear(ba, 256) == 256);
	CU_ASSERT(spdk_bit_array_find_first_clear(ba, 256) == UINT32_MAX);

	/* Clear bits 0 through 31 */
	for (i = 0; i < 32; i++) {
@@ -150,7 +150,7 @@ test_find(void)

	for (i = 32; i < 256; i++) {
		CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == i);
		CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == 256);
		CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == UINT32_MAX);
	}

	/* Clear bit 255 */
@@ -166,7 +166,7 @@ test_find(void)
		CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == 255);
	}

	CU_ASSERT(spdk_bit_array_find_first_clear(ba, 256) == 256);
	CU_ASSERT(spdk_bit_array_find_first_clear(ba, 256) == UINT32_MAX);

	spdk_bit_array_free(&ba);
}