From d946124a01c39939e133557d6ea11aa7656700a9 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 22 Jul 2020 22:40:41 +0200 Subject: [PATCH 1/2] Calculate CRC for runtime metadata sections only on clean load During recovery procedure there is no guarantee that checksums of runtime sections were flushed correctly before dirty shutdown. Signed-off-by: Robert Baldyga --- src/metadata/metadata_hash.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/metadata/metadata_hash.c b/src/metadata/metadata_hash.c index 9f4b971..b9f1b4b 100644 --- a/src/metadata/metadata_hash.c +++ b/src/metadata/metadata_hash.c @@ -1273,8 +1273,8 @@ static void ocf_medatata_hash_check_crc_sb_config(ocf_pipeline_t pipeline, ocf_pipeline_next(pipeline); } -static void ocf_medatata_hash_check_crc(ocf_pipeline_t pipeline, - void *priv, ocf_pipeline_arg_t arg) +static void ocf_medatata_hash_check_crc_skip(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg, bool skip_on_dirty_shutdown) { struct ocf_metadata_hash_context *context = priv; int segment = ocf_pipeline_arg_get_int(arg); @@ -1286,6 +1286,9 @@ static void ocf_medatata_hash_check_crc(ocf_pipeline_t pipeline, ctrl = (struct ocf_metadata_hash_ctrl *)cache->metadata.iface_priv; sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config); + if (!sb_config->clean_shutdown && skip_on_dirty_shutdown) + OCF_PL_NEXT_RET(pipeline); + crc = ocf_metadata_raw_checksum(cache, &(ctrl->raw_desc[segment])); if (crc != sb_config->checksum[segment]) { @@ -1299,6 +1302,18 @@ static void ocf_medatata_hash_check_crc(ocf_pipeline_t pipeline, ocf_pipeline_next(pipeline); } +static void ocf_medatata_hash_check_crc(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) +{ + ocf_medatata_hash_check_crc_skip(pipeline, priv, arg, false); +} + +static void ocf_medatata_hash_check_crc_if_clean(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) +{ + ocf_medatata_hash_check_crc_skip(pipeline, priv, arg, true); +} + static void ocf_medatata_hash_load_superblock_post(ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { @@ -1409,14 +1424,18 @@ struct ocf_pipeline_arg ocf_metadata_hash_load_sb_load_segment_args[] = { }; struct ocf_pipeline_arg ocf_metadata_hash_load_sb_check_crc_args[] = { - OCF_PL_ARG_INT(metadata_segment_sb_runtime), OCF_PL_ARG_INT(metadata_segment_part_config), - OCF_PL_ARG_INT(metadata_segment_part_runtime), OCF_PL_ARG_INT(metadata_segment_core_config), OCF_PL_ARG_INT(metadata_segment_core_uuid), OCF_PL_ARG_TERMINATOR(), }; +struct ocf_pipeline_arg ocf_metadata_hash_load_sb_check_crc_args_clean[] = { + OCF_PL_ARG_INT(metadata_segment_sb_runtime), + OCF_PL_ARG_INT(metadata_segment_part_runtime), + OCF_PL_ARG_TERMINATOR(), +}; + struct ocf_pipeline_properties ocf_metadata_hash_load_sb_pipeline_props = { .priv_size = sizeof(struct ocf_metadata_hash_context), .finish = ocf_metadata_hash_load_superblock_finish, @@ -1428,6 +1447,8 @@ struct ocf_pipeline_properties ocf_metadata_hash_load_sb_pipeline_props = { OCF_PL_STEP(ocf_medatata_hash_check_crc_sb_config), OCF_PL_STEP_FOREACH(ocf_medatata_hash_check_crc, ocf_metadata_hash_load_sb_check_crc_args), + OCF_PL_STEP_FOREACH(ocf_medatata_hash_check_crc_if_clean, + ocf_metadata_hash_load_sb_check_crc_args_clean), OCF_PL_STEP(ocf_medatata_hash_load_superblock_post), OCF_PL_STEP_TERMINATOR(), }, From d5ecdc16dd30bcf0a9c17e9c6b758056c6e1c0fa Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Thu, 23 Jul 2020 13:46:38 +0200 Subject: [PATCH 2/2] Make CRC mismatch on recovery a warning instead of error Signed-off-by: Robert Baldyga --- src/metadata/metadata_hash.c | 14 ++++++++++---- src/mngt/ocf_mngt_cache.c | 12 ++++++++++-- src/mngt/ocf_mngt_core.c | 5 ++++- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/metadata/metadata_hash.c b/src/metadata/metadata_hash.c index b9f1b4b..d2a1c6c 100644 --- a/src/metadata/metadata_hash.c +++ b/src/metadata/metadata_hash.c @@ -1293,10 +1293,16 @@ static void ocf_medatata_hash_check_crc_skip(ocf_pipeline_t pipeline, if (crc != sb_config->checksum[segment]) { /* Checksum does not match */ - ocf_cache_log(cache, log_err, - "Loading %s ERROR, invalid checksum", - ocf_metadata_hash_raw_names[segment]); - OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL); + if (!sb_config->clean_shutdown) { + ocf_cache_log(cache, log_warn, + "Loading %s WARNING, invalid checksum", + ocf_metadata_hash_raw_names[segment]); + } else { + ocf_cache_log(cache, log_err, + "Loading %s ERROR, invalid checksum", + ocf_metadata_hash_raw_names[segment]); + OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL); + } } ocf_pipeline_next(pipeline); diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index 0d49f91..86b32d5 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -373,6 +373,7 @@ static int _ocf_mngt_init_instance_add_cores( ocf_core_id_t core_id; int ret = -1; uint64_t hd_lines = 0; + uint64_t length; OCF_ASSERT_PLUGGED(cache); @@ -439,8 +440,15 @@ static int _ocf_mngt_init_instance_add_cores( ocf_core_seq_cutoff_init(core); - hd_lines = ocf_bytes_2_lines(cache, - ocf_volume_get_length(&core->volume)); + length = ocf_volume_get_length(&core->volume); + if (length != core->conf_meta->length) { + ocf_cache_log(cache, log_err, + "Size of core volume doesn't match with" + " the size stored in cache metadata!"); + goto err; + } + + hd_lines = ocf_bytes_2_lines(cache, length); if (hd_lines) { ocf_cache_log(cache, log_info, diff --git a/src/mngt/ocf_mngt_core.c b/src/mngt/ocf_mngt_core.c index b3f3dfd..2db7479 100644 --- a/src/mngt/ocf_mngt_core.c +++ b/src/mngt/ocf_mngt_core.c @@ -279,7 +279,10 @@ static void ocf_mngt_cache_try_add_core_insert(ocf_pipeline_t pipeline, if (result) OCF_PL_FINISH_RET(pipeline, result); - if (!ocf_volume_get_length(volume)) { + if (ocf_volume_get_length(volume) != core->conf_meta->length) { + ocf_cache_log(cache, log_err, + "Size of core volume doesn't match with" + " the size stored in cache metadata!"); result = -OCF_ERR_CORE_NOT_AVAIL; goto error_after_open; }