Fail cache recovery in case of erroneous mapping

Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
Adam Rutkowski 2021-12-19 15:58:26 +01:00
parent 913966e3f9
commit 294e02bc1b
4 changed files with 75 additions and 7 deletions

View File

@ -1552,6 +1552,26 @@ void ocf_metadata_clear_dirty_if_invalid(struct ocf_cache *cache,
}
}
bool ocf_metadata_check(struct ocf_cache *cache, ocf_cache_line_t line)
{
switch (cache->metadata.line_size) {
case ocf_cache_line_size_4:
return _ocf_metadata_check_u8(cache, line);
case ocf_cache_line_size_8:
return _ocf_metadata_check_u16(cache, line);
case ocf_cache_line_size_16:
return _ocf_metadata_check_u32(cache, line);
case ocf_cache_line_size_32:
return _ocf_metadata_check_u64(cache, line);
case ocf_cache_line_size_64:
return _ocf_metadata_check_u128(cache, line);
case ocf_cache_line_size_none:
default:
ENV_BUG_ON(1);
return false;
}
}
int ocf_metadata_init(struct ocf_cache *cache,
ocf_cache_line_size_t cache_line_size)
{

View File

@ -220,4 +220,14 @@ static inline ocf_cache_line_t ocf_metadata_collision_table_entries(
void ocf_metadata_zero_superblock(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *context);
/**
* @brief Check for incorrect status bits combinations
*
* @param cache Cache instance
* @param line Cache line
* @return true - status bits are correct
* @return false - status bits have illegal value
*/
bool ocf_metadata_check(struct ocf_cache *cache, ocf_cache_line_t line);
#endif /* METADATA_H_ */

View File

@ -263,6 +263,23 @@ static void _ocf_metadata_clear_dirty_if_invalid_##type(struct ocf_cache *cache,
\
map[line].dirty &= (mask & map[line].valid) | (~mask); \
} \
\
/* true if no incorrect combination of status bits */ \
static bool _ocf_metadata_check_##type(struct ocf_cache *cache, \
ocf_cache_line_t line) \
{ \
struct ocf_metadata_ctrl *ctrl = \
(struct ocf_metadata_ctrl *) cache->metadata.priv; \
\
struct ocf_metadata_raw *raw = \
&ctrl->raw_desc[metadata_segment_collision]; \
\
struct ocf_metadata_map_##type *map = raw->mem_pool; \
\
_raw_bug_on(raw, line); \
\
return (map[line].dirty & (~map[line].valid)) == 0; \
} \
#define ocf_metadata_bit_funcs(type) \
ocf_metadata_bit_struct(type); \

View File

@ -495,7 +495,7 @@ static void _recovery_reset_cline_metadata(struct ocf_cache *cache,
ocf_cleaning_init_cache_block(cache, cline);
}
static void _ocf_mngt_rebuild_metadata(ocf_cache_t cache)
static int _ocf_mngt_rebuild_metadata(ocf_cache_t cache)
{
ocf_cache_line_t cline;
ocf_core_id_t core_id;
@ -512,25 +512,40 @@ static void _ocf_mngt_rebuild_metadata(ocf_cache_t cache)
OCF_COND_RESCHED(step, 128);
ocf_metadata_get_core_info(cache, cline, &core_id, &core_line);
metadata_clear_dirty_if_invalid(cache, cline);
if (!ocf_metadata_check(cache, cline) ||
core_id > OCF_CORE_MAX) {
ocf_cache_log(cache, log_err, "Inconsistent mapping "
"detected in on-disk metadata - "
"refusing to recover cache.\n");
return -OCF_ERR_INVAL;
}
any_valid = metadata_clear_valid_if_clean(cache, cline);
if (!any_valid || core_id >= OCF_CORE_MAX) {
if (!any_valid || core_id == OCF_CORE_MAX) {
/* Reset metadata for not mapped or clean cache line */
_recovery_reset_cline_metadata(cache, cline);
continue;
}
if (!cache->core[core_id].added) {
ocf_cache_log(cache, log_err, "Stale mapping in "
"on-disk metadata - refusing to "
"recover cache.\n");
return -OCF_ERR_INVAL;
}
/* Rebuild metadata for mapped cache line */
ocf_cline_rebuild_metadata(cache, core_id, core_line, cline);
}
ocf_metadata_end_exclusive_access(&cache->metadata.lock);
return 0;
}
static void _ocf_mngt_recovery_rebuild_metadata(ocf_cache_t cache)
static int _ocf_mngt_recovery_rebuild_metadata(ocf_cache_t cache)
{
_ocf_mngt_rebuild_metadata(cache);
return _ocf_mngt_rebuild_metadata(cache);
}
static inline ocf_error_t _ocf_init_cleaning_policy(ocf_cache_t cache,
@ -556,9 +571,12 @@ static void _ocf_mngt_load_post_metadata_load(ocf_pipeline_t pipeline,
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
ocf_error_t result;
int ret;
if (context->metadata.shutdown_status != ocf_metadata_clean_shutdown) {
_ocf_mngt_recovery_rebuild_metadata(cache);
ret = _ocf_mngt_recovery_rebuild_metadata(cache);
if (ret)
OCF_PL_FINISH_RET(pipeline, ret);
__populate_free(cache);
}
@ -2113,8 +2131,11 @@ static void _ocf_mngt_standby_recovery(ocf_pipeline_t pipeline,
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
int ret;
_ocf_mngt_recovery_rebuild_metadata(cache);
ret = _ocf_mngt_recovery_rebuild_metadata(cache);
if (ret)
OCF_PL_FINISH_RET(pipeline, ret);
__populate_free(cache);
ocf_pipeline_next(pipeline);