diff --git a/inc/ocf_def.h b/inc/ocf_def.h index 320fdcf..3f80786 100644 --- a/inc/ocf_def.h +++ b/inc/ocf_def.h @@ -83,7 +83,7 @@ /** * Maximum value of a valid core sequence number */ -#define OCF_SEQ_NO_MAX (65535UL) +#define OCF_SEQ_NO_MAX ((1ULL << (sizeof(ocf_core_id_t) * 8)) - 1) /* * Invalid value of core sequence number */ diff --git a/src/engine/cache_engine.c b/src/engine/cache_engine.c index dc72669..fdfa7af 100644 --- a/src/engine/cache_engine.c +++ b/src/engine/cache_engine.c @@ -286,3 +286,10 @@ void ocf_engine_hndl_ops_req(struct ocf_request *req) ocf_engine_push_req_back(req, true); } + +bool ocf_req_cache_mode_has_lazy_write(ocf_req_cache_mode_t mode) +{ + return ocf_cache_mode_is_valid((ocf_cache_mode_t)mode) && + ocf_mngt_cache_mode_has_lazy_write( + (ocf_cache_mode_t)mode); +} diff --git a/src/engine/cache_engine.h b/src/engine/cache_engine.h index f98dbb0..40d5c96 100644 --- a/src/engine/cache_engine.h +++ b/src/engine/cache_engine.h @@ -52,17 +52,7 @@ static inline const char *ocf_get_io_iface_name(ocf_cache_mode_t cache_mode) return iface ? iface->name : "Unknown"; } -static inline bool ocf_cache_mode_is_valid(ocf_cache_mode_t mode) -{ - return mode >= ocf_cache_mode_wt && mode < ocf_cache_mode_max; -} - -static inline bool ocf_req_cache_mode_has_lazy_write(ocf_req_cache_mode_t mode) -{ - return ocf_cache_mode_is_valid((ocf_cache_mode_t)mode) && - ocf_mngt_cache_mode_has_lazy_write( - (ocf_cache_mode_t)mode); -} +bool ocf_req_cache_mode_has_lazy_write(ocf_req_cache_mode_t mode); bool ocf_fallback_pt_is_on(ocf_cache_t cache); diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index c33a748..6867c03 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -1609,6 +1609,16 @@ void ocf_metadata_error(struct ocf_cache *cache) cache->device->metadata_error = -1; } +typedef void (*ocf_metadata_read_sb_end_t)( + struct ocf_metadata_read_sb_ctx *context); + +struct ocf_metadata_load_properties_ctx +{ + ocf_cache_t cache; + ocf_metadata_load_properties_end_t cmpl; + void *priv; +}; + static void ocf_metadata_load_properties_cmpl( struct ocf_metadata_read_sb_ctx *context) { diff --git a/src/metadata/metadata_superblock.c b/src/metadata/metadata_superblock.c index 662d621..c4140ff 100644 --- a/src/metadata/metadata_superblock.c +++ b/src/metadata/metadata_superblock.c @@ -98,55 +98,115 @@ static void ocf_metadata_store_segment(ocf_pipeline_t pipeline, ocf_pipeline_next(pipeline); } -static void ocf_metadata_check_crc_sb_config(ocf_pipeline_t pipeline, - void *priv, ocf_pipeline_arg_t arg) + +#define ocf_log_invalid_superblock(param) \ + ocf_log(ctx, log_err, \ + "Loading %s: invalid %s\n", \ + ocf_metadata_segment_names[ \ + metadata_segment_sb_config], \ + param); + + +int ocf_metadata_validate_superblock(ocf_ctx_t ctx, + struct ocf_superblock_config *superblock) { - struct ocf_metadata_context *context = priv; - struct ocf_metadata_ctrl *ctrl; - struct ocf_superblock_config *sb_config; - ocf_cache_t cache = context->cache; - int segment = metadata_segment_sb_config; uint32_t crc; - ctrl = (struct ocf_metadata_ctrl *)cache->metadata.priv; - sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config); - - crc = env_crc32(0, (void *)sb_config, - offsetof(struct ocf_superblock_config, checksum)); - - if (crc != sb_config->checksum[segment]) { - /* Checksum does not match */ - ocf_cache_log(cache, log_err, - "Loading %s ERROR, invalid checksum\n", - ocf_metadata_segment_names[segment]); - OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL); + if (superblock->magic_number != CACHE_MAGIC_NUMBER) { + ocf_log(ctx, log_info, "Cannot detect pre-existing metadata\n"); + return -OCF_ERR_NO_METADATA; } - ocf_pipeline_next(pipeline); + if (METADATA_VERSION() != superblock->metadata_version) { + ocf_log(ctx, log_err, "Metadata version mismatch!\n"); + return -OCF_ERR_METADATA_VER; + } + + crc = env_crc32(0, (void *)superblock, + offsetof(struct ocf_superblock_config, checksum)); + + if (crc != superblock->checksum[metadata_segment_sb_config]) { + ocf_log_invalid_superblock("checksum"); + return -OCF_ERR_INVAL; + } + + if (superblock->clean_shutdown > ocf_metadata_clean_shutdown) { + ocf_log_invalid_superblock("shutdown status"); + return -OCF_ERR_INVAL; + } + + if (superblock->dirty_flushed > DIRTY_FLUSHED) { + ocf_log_invalid_superblock("flush status"); + return -OCF_ERR_INVAL; + } + + if (superblock->flapping_idx > 1) { + ocf_log_invalid_superblock("flapping index"); + return -OCF_ERR_INVAL; + } + + if (superblock->cache_mode < 0 || + superblock->cache_mode >= ocf_cache_mode_max) { + ocf_log_invalid_superblock("cache mode"); + return -OCF_ERR_INVAL; + } + + if (env_strnlen(superblock->name, sizeof(superblock->name)) >= + OCF_CACHE_NAME_SIZE) { + ocf_log_invalid_superblock("name"); + return -OCF_ERR_INVAL; + } + + if (superblock->valid_parts_no > OCF_USER_IO_CLASS_MAX) { + ocf_log_invalid_superblock("partition count"); + return -OCF_ERR_INVAL; + } + + if (!ocf_cache_line_size_is_valid(superblock->line_size)) { + ocf_log_invalid_superblock("cache line size"); + return -OCF_ERR_INVAL; + } + + if ((unsigned)superblock->metadata_layout >= ocf_metadata_layout_max) { + ocf_log_invalid_superblock("metadata layout"); + return -OCF_ERR_INVAL; + } + + if (superblock->core_count > OCF_CORE_MAX) { + ocf_log_invalid_superblock("core count"); + return -OCF_ERR_INVAL; + } + + if (superblock->cleaning_policy_type < 0 || + superblock->cleaning_policy_type >= ocf_cleaning_max) { + ocf_log_invalid_superblock("cleaning policy"); + return -OCF_ERR_INVAL; + } + + if (superblock->promotion_policy_type < 0 || + superblock->promotion_policy_type >= + ocf_promotion_max) { + ocf_log_invalid_superblock("promotion policy"); + return -OCF_ERR_INVAL; + } + + return 0; } -static void ocf_metadata_load_superblock_post(ocf_pipeline_t pipeline, +static void _ocf_metadata_validate_superblock(ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { struct ocf_metadata_context *context = priv; struct ocf_metadata_ctrl *ctrl; - struct ocf_superblock_config *sb_config; - ocf_cache_t cache = context->cache; + struct ocf_superblock_config *superblock; + int ret; - ctrl = (struct ocf_metadata_ctrl *)cache->metadata.priv; - sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config); + ctrl = (struct ocf_metadata_ctrl *)context->ctrl; + superblock = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config); - if (sb_config->core_count > OCF_CORE_MAX) { - ocf_cache_log(cache, log_err, - "Loading cache state ERROR, invalid cores count\n"); - OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL); - } - - if (sb_config->valid_parts_no > OCF_USER_IO_CLASS_MAX) { - ocf_cache_log(cache, log_err, - "Loading cache state ERROR, invalid partition count\n"); - OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL); - } + ret = ocf_metadata_validate_superblock(context->cache->owner, superblock); + if (ret) + OCF_PL_FINISH_RET(pipeline, ret); ocf_pipeline_next(pipeline); } @@ -222,12 +282,11 @@ struct ocf_pipeline_properties ocf_metadata_load_sb_pipeline_props = { ocf_metadata_load_sb_store_segment_args), OCF_PL_STEP_ARG_INT(ocf_metadata_load_segment, metadata_segment_sb_config), - OCF_PL_STEP(ocf_metadata_check_crc_sb_config), + OCF_PL_STEP(_ocf_metadata_validate_superblock), OCF_PL_STEP_FOREACH(ocf_metadata_load_segment, ocf_metadata_load_sb_load_segment_args), OCF_PL_STEP_FOREACH(ocf_metadata_check_crc, ocf_metadata_load_sb_load_segment_args), - OCF_PL_STEP(ocf_metadata_load_superblock_post), OCF_PL_STEP_TERMINATOR(), }, }; @@ -288,12 +347,11 @@ struct ocf_pipeline_properties ocf_metadata_load_sb_recov_pipeline_props = { ocf_metadata_load_sb_store_segment_args), OCF_PL_STEP_ARG_INT(ocf_metadata_load_segment, metadata_segment_sb_config), - OCF_PL_STEP(ocf_metadata_check_crc_sb_config), + OCF_PL_STEP(_ocf_metadata_validate_superblock), OCF_PL_STEP_FOREACH(ocf_metadata_load_segment, ocf_metadata_load_sb_recov_load_segment_args), OCF_PL_STEP_FOREACH(ocf_metadata_check_crc, ocf_metadata_load_sb_recov_load_segment_args), - OCF_PL_STEP(ocf_metadata_load_superblock_post), OCF_PL_STEP_TERMINATOR(), }, }; @@ -573,47 +631,6 @@ unsigned ocf_metadata_superblock_get_next_flapping_idx( return (sb->config->flapping_idx + 1) % 2; } -int ocf_metadata_validate_superblock(ocf_ctx_t ctx, - struct ocf_superblock_config *superblock) -{ - if (superblock->magic_number != CACHE_MAGIC_NUMBER) { - ocf_log(ctx, log_info, "Cannot detect pre-existing metadata\n"); - return -OCF_ERR_NO_METADATA; - } - - if (METADATA_VERSION() != superblock->metadata_version) { - ocf_log(ctx, log_err, "Metadata version mismatch!\n"); - return -OCF_ERR_METADATA_VER; - } - - if (!ocf_cache_line_size_is_valid(superblock->line_size)) { - ocf_log(ctx, log_err, "ERROR: Invalid cache line size!\n"); - return -OCF_ERR_INVAL; - } - - if ((unsigned)superblock->metadata_layout >= ocf_metadata_layout_max) { - ocf_log(ctx, log_err, "ERROR: Invalid metadata layout!\n"); - return -OCF_ERR_INVAL; - } - - if (superblock->cache_mode >= ocf_cache_mode_max) { - ocf_log(ctx, log_err, "ERROR: Invalid cache mode!\n"); - return -OCF_ERR_INVAL; - } - - if (superblock->clean_shutdown > ocf_metadata_clean_shutdown) { - ocf_log(ctx, log_err, "ERROR: Invalid shutdown status!\n"); - return -OCF_ERR_INVAL; - } - - if (superblock->dirty_flushed > DIRTY_FLUSHED) { - ocf_log(ctx, log_err, "ERROR: Invalid flush status!\n"); - return -OCF_ERR_INVAL; - } - - return 0; -} - static void ocf_metadata_read_sb_complete(struct ocf_io *io, int error) { struct ocf_metadata_read_sb_ctx *context = io->priv1; diff --git a/src/ocf_cache.c b/src/ocf_cache.c index c784016..c315f9d 100644 --- a/src/ocf_cache.c +++ b/src/ocf_cache.c @@ -39,6 +39,11 @@ int ocf_cache_set_name(ocf_cache_t cache, const char *src, size_t src_size) src, src_size); } +bool ocf_cache_mode_is_valid(ocf_cache_mode_t mode) +{ + return mode >= ocf_cache_mode_wt && mode < ocf_cache_mode_max; +} + const char *ocf_cache_get_name(ocf_cache_t cache) { OCF_CHECK_NULL(cache); diff --git a/src/ocf_cache_priv.h b/src/ocf_cache_priv.h index fdb6e42..041bc6f 100644 --- a/src/ocf_cache_priv.h +++ b/src/ocf_cache_priv.h @@ -179,4 +179,6 @@ int ocf_cache_set_name(ocf_cache_t cache, const char *src, size_t src_size); int ocf_cache_volume_type_init(ocf_ctx_t ctx); +bool ocf_cache_mode_is_valid(ocf_cache_mode_t mode); + #endif /* __OCF_CACHE_PRIV_H__ */