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: Jim 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: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Ziye Yang <optimistyzy@gmail.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
This commit is contained in:
Jim Harris 2018-10-05 09:37:04 -07:00
parent 76c5ec4ca5
commit 7c56c393ba
4 changed files with 28 additions and 14 deletions

View File

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

View File

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

View File

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

View File

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