diff --git a/inc/ocf_cache.h b/inc/ocf_cache.h index 683ee7793..1f69fa60f 100644 --- a/inc/ocf_cache.h +++ b/inc/ocf_cache.h @@ -261,6 +261,17 @@ const struct ocf_volume_uuid *ocf_cache_get_uuid(ocf_cache_t cache); */ ocf_ctx_t ocf_cache_get_ctx(ocf_cache_t cache); +/** + * @brief Get OCF cleaner of given cache object + * + * @param[in] cache Cache object + * + * @retval OCF cleaner, NULL if cache is in standby mode, + * cache device is not attached (cleaner not initialized) + * or cleaner is disabled + */ +ocf_cleaner_t ocf_cache_get_cleaner(ocf_cache_t cache); + /** * @brief Get volume type id of given cache object * diff --git a/inc/ocf_def.h b/inc/ocf_def.h index 330a3a359..049c756c5 100644 --- a/inc/ocf_def.h +++ b/inc/ocf_def.h @@ -88,7 +88,9 @@ * for invalid OCF_CORE_ID_INVALID. */ #define OCF_CORE_NUM OCF_CONFIG_MAX_CORES -_Static_assert(OCF_CORE_NUM < OCF_MAX_T(uint32_t, OCF_CORE_ID_BITS)); +_Static_assert(OCF_MAX_T(uint32_t, OCF_CORE_ID_BITS) > OCF_CORE_NUM, + "Not enough core ID bits (OCF_CORE_ID_BITS) to " + "store maximum number of cores (OCF_CORE_NUM)"); /** * Minimum value of a valid core ID */ diff --git a/src/cleaning/cleaning.h b/src/cleaning/cleaning.h index f67a79e1d..1e56af270 100644 --- a/src/cleaning/cleaning.h +++ b/src/cleaning/cleaning.h @@ -22,7 +22,7 @@ struct ocf_request; struct cleaning_policy_config { uint8_t data[CLEANING_POLICY_CONFIG_BYTES]; -}; +} __attribute__((aligned(4))); struct cleaning_policy { union { diff --git a/src/metadata/metadata_collision.h b/src/metadata/metadata_collision.h index 01d7a7ed2..f444c9b14 100644 --- a/src/metadata/metadata_collision.h +++ b/src/metadata/metadata_collision.h @@ -24,7 +24,8 @@ struct ocf_metadata_list_info { } __attribute__((packed)); /* Keep the struct ocf_metadata_list_info size of 8 bytes */ -_Static_assert(sizeof(struct ocf_metadata_list_info) == sizeof(uint64_t)); +_Static_assert(sizeof(struct ocf_metadata_list_info) == sizeof(uint64_t), + "Size of struct ocf_metadata_list_info is not equal to 8 bytes"); struct ocf_hash_entry { union { diff --git a/src/ocf_cache.c b/src/ocf_cache.c index 55f99e877..3fbe12c06 100644 --- a/src/ocf_cache.c +++ b/src/ocf_cache.c @@ -287,6 +287,22 @@ ocf_ctx_t ocf_cache_get_ctx(ocf_cache_t cache) return cache->owner; } +ocf_cleaner_t ocf_cache_get_cleaner(ocf_cache_t cache) +{ + OCF_CHECK_NULL(cache); + + if (ocf_cache_is_standby(cache)) + return NULL; + + if (!ocf_cache_is_device_attached(cache)) + return NULL; + + if (cache->conf_meta->cleaner_disabled) + return NULL; + + return &cache->cleaner; +} + void ocf_cache_set_priv(ocf_cache_t cache, void *priv) { OCF_CHECK_NULL(cache); diff --git a/src/ocf_lru.c b/src/ocf_lru.c index 7a0d959e4..af35aa2a8 100644 --- a/src/ocf_lru.c +++ b/src/ocf_lru.c @@ -1031,6 +1031,7 @@ static int ocf_lru_populate_handle(ocf_parallelize_t parallelize, uint32_t partial_chunk_lines = 0; uint32_t num_chunks, chunk_idx, chunk_lines; uint32_t ci, j; + int result; /* Check if this shard has a partial last chunk */ if (remainder > (uint32_t)shard_id * OCF_LRU_CHUNK_SIZE) { @@ -1044,7 +1045,9 @@ static int ocf_lru_populate_handle(ocf_parallelize_t parallelize, if (num_chunks == 0) return 0; - ocf_generator_bisect_init(&generator, num_chunks, 0); + result = ocf_generator_bisect_init(&generator, num_chunks, 0); + if (result) + return result; list = ocf_lru_get_list(&cache->free, shard_id, true); diff --git a/src/promotion/promotion.h b/src/promotion/promotion.h index f4005181a..612b5b62d 100644 --- a/src/promotion/promotion.h +++ b/src/promotion/promotion.h @@ -15,7 +15,7 @@ struct promotion_policy_config { uint8_t data[PROMOTION_POLICY_CONFIG_BYTES]; -}; +} __attribute__((aligned(4))); typedef struct ocf_promotion_policy *ocf_promotion_policy_t; diff --git a/src/utils/utils_generator.c b/src/utils/utils_generator.c index 47ab7e653..e04c80291 100644 --- a/src/utils/utils_generator.c +++ b/src/utils/utils_generator.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2022 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -29,20 +30,32 @@ static inline uint32_t bitreverse32(register uint32_t x) * returned by the generator is limit - 1) * @param[in] offset Offset at which generator should start * - * @return Reversed value + * @return Zero when success, otherwise an error */ -void ocf_generator_bisect_init( +int ocf_generator_bisect_init( struct ocf_generator_bisect_state *generator, uint32_t limit, uint32_t offset) { unsigned clz; uint32_t maplen; - clz = __builtin_clz(limit - 1); - maplen = 1 << (32 - clz); + if (limit == 0) + return -OCF_ERR_INVAL; + + if (offset >= limit) + return -OCF_ERR_INVAL; + + if (limit > 1) { + clz = __builtin_clz(limit - 1); + maplen = 1 << (32 - clz); + } else { + maplen = 1; + } generator->curr = (uint64_t)offset * maplen / limit; generator->limit = limit; + + return 0; } /** @@ -180,6 +193,9 @@ uint32_t ocf_generator_bisect_next( uint32_t maplen; uint32_t value; + if (generator->limit == 1) + return 0; + clz = __builtin_clz(generator->limit - 1); maplen = 1 << (32 - clz); diff --git a/src/utils/utils_generator.h b/src/utils/utils_generator.h index 068602d0b..df8cb1ba1 100644 --- a/src/utils/utils_generator.h +++ b/src/utils/utils_generator.h @@ -1,5 +1,6 @@ /* * Copyright(c) 2022 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,7 +14,7 @@ struct ocf_generator_bisect_state { uint32_t limit; }; -void ocf_generator_bisect_init( +int ocf_generator_bisect_init( struct ocf_generator_bisect_state *generator, uint32_t limit, uint32_t offset);