Introduce metadata superblock & segment structures

Refactoring metadata superblock and segment ops code
to make it less tightly coupled.

Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
Adam Rutkowski 2020-12-11 15:41:37 +01:00
parent 3eb5568608
commit 822cd7c45a
7 changed files with 254 additions and 40 deletions

View File

@ -394,7 +394,6 @@ static void ocf_metadata_raw_info(struct ocf_cache *cache,
void ocf_metadata_deinit_variable_size(struct ocf_cache *cache)
{
int result = 0;
uint32_t i = 0;
struct ocf_metadata_ctrl *ctrl = (struct ocf_metadata_ctrl *)
@ -409,8 +408,7 @@ void ocf_metadata_deinit_variable_size(struct ocf_cache *cache)
*/
for (i = metadata_segment_variable_size_start;
i < metadata_segment_max; i++) {
result |= ocf_metadata_raw_deinit(cache,
&(ctrl->raw_desc[i]));
ocf_metadata_segment_destroy(cache, ctrl->segment[i]);
}
}
@ -440,11 +438,16 @@ static void ocf_metadata_deinit_fixed_size(struct ocf_cache *cache)
struct ocf_metadata_ctrl *ctrl = (struct ocf_metadata_ctrl *)
cache->metadata.priv;
struct ocf_metadata_segment *superblock =
ctrl->segment[metadata_segment_sb_config];
for (i = 0; i < metadata_segment_fixed_size_max; i++) {
result |= ocf_metadata_raw_deinit(cache,
&(ctrl->raw_desc[i]));
if (i != metadata_segment_sb_config)
ocf_metadata_segment_destroy(cache, ctrl->segment[i]);
}
ocf_metadata_superblock_destroy(cache, superblock);
env_vfree(ctrl);
cache->metadata.priv = NULL;
@ -513,6 +516,7 @@ static int ocf_metadata_init_fixed_size(struct ocf_cache *cache,
struct ocf_core_meta_runtime *core_meta_runtime;
struct ocf_user_part_config *part_config;
struct ocf_user_part_runtime *part_runtime;
struct ocf_metadata_segment *superblock;
ocf_core_t core;
ocf_core_id_t core_id;
uint32_t i = 0;
@ -529,9 +533,25 @@ static int ocf_metadata_init_fixed_size(struct ocf_cache *cache,
return -OCF_ERR_NO_MEM;
metadata->priv = ctrl;
result = ocf_metadata_superblock_init(
&ctrl->segment[metadata_segment_sb_config], cache,
&ctrl->raw_desc[metadata_segment_sb_config]);
if (result) {
ocf_metadata_deinit_fixed_size(cache);
return result;
}
superblock = ctrl->segment[metadata_segment_sb_config];
for (i = 0; i < metadata_segment_fixed_size_max; i++) {
result |= ocf_metadata_raw_init(cache, NULL, NULL,
&(ctrl->raw_desc[i]));
if (i == metadata_segment_sb_config)
continue;
result |= ocf_metadata_segment_init(
&ctrl->segment[i],
cache,
&ctrl->raw_desc[i],
NULL, NULL,
superblock);
if (result)
break;
}
@ -609,6 +629,7 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache,
(struct ocf_cache_line_settings *)&cache->metadata.settings;
ocf_flush_page_synch_t lock_page, unlock_page;
uint64_t device_lines;
struct ocf_metadata_segment *superblock;
OCF_DEBUG_TRACE(cache);
@ -669,6 +690,8 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache,
OCF_DEBUG_PARAM(cache, "Metadata end pages = %u", ctrl->start_page
+ ctrl->count_pages);
superblock = ctrl->segment[metadata_segment_sb_config];
/*
* Initialize all dynamic size RAW types
*/
@ -683,8 +706,12 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache,
lock_page = unlock_page = NULL;
}
result |= ocf_metadata_raw_init(cache, lock_page, unlock_page,
&(ctrl->raw_desc[i]));
result |= ocf_metadata_segment_init(
&ctrl->segment[i],
cache,
&ctrl->raw_desc[i],
lock_page, unlock_page,
superblock);
if (result)
goto finalize;
@ -991,6 +1018,7 @@ void ocf_metadata_flush_all(ocf_cache_t cache,
context->priv = priv;
context->pipeline = pipeline;
context->cache = cache;
context->ctrl = cache->metadata.priv;
ocf_pipeline_next(pipeline);
}
@ -1113,6 +1141,7 @@ void ocf_metadata_load_all(ocf_cache_t cache,
context->priv = priv;
context->pipeline = pipeline;
context->cache = cache;
context->ctrl = cache->metadata.priv;
ocf_pipeline_next(pipeline);
}
@ -1272,6 +1301,7 @@ static void _ocf_metadata_load_recovery_legacy(ocf_cache_t cache,
context->priv = priv;
context->pipeline = pipeline;
context->cache = cache;
context->ctrl = cache->metadata.priv;
ocf_pipeline_next(pipeline);
}
@ -1416,6 +1446,7 @@ static void _ocf_metadata_load_recovery_atomic(ocf_cache_t cache,
context->priv = priv;
context->pipeline = pipeline;
context->cache = cache;
context->ctrl = cache->metadata.priv;
ocf_pipeline_next(pipeline);
}

View File

@ -8,6 +8,7 @@
#include <ocf/ocf_def.h>
#include "../ocf_cache_priv.h"
#include "metadata_segment.h"
#include "metadata_segment_id.h"
#include "metadata_raw.h"
@ -23,6 +24,7 @@ struct ocf_metadata_ctrl {
uint32_t device_lines;
size_t mapping_size;
struct ocf_metadata_raw raw_desc[metadata_segment_max];
struct ocf_metadata_segment *segment[metadata_segment_max];
};
struct ocf_metadata_context {
@ -30,6 +32,7 @@ struct ocf_metadata_context {
void *priv;
ocf_pipeline_t pipeline;
ocf_cache_t cache;
struct ocf_metadata_ctrl *ctrl;
struct ocf_metadata_raw segment_copy[metadata_segment_fixed_size_max];
};

View File

@ -6,6 +6,8 @@
#ifndef __METADATA_RAW_H__
#define __METADATA_RAW_H__
#include "metadata_segment_id.h"
/**
* @file metadata_raw.h
* @brief Metadata RAW container implementation
@ -306,4 +308,9 @@ static inline void _raw_bug_on(struct ocf_metadata_raw *raw, uint32_t entry)
int _raw_ram_flush_do_page_cmp(const void *item1, const void *item2);
static inline void *ocf_metadata_raw_get_mem(struct ocf_metadata_raw *raw)
{
return raw->mem_pool;
}
#endif /* METADATA_RAW_H_ */

View File

@ -4,6 +4,65 @@
*/
#include "metadata_internal.h"
#include "metadata_superblock.h"
#include "metadata_raw.h"
int ocf_metadata_segment_init_in_place(
struct ocf_metadata_segment *segment,
struct ocf_cache *cache,
struct ocf_metadata_raw *raw,
ocf_flush_page_synch_t lock_page_pfn,
ocf_flush_page_synch_t unlock_page_pfn,
struct ocf_metadata_segment *superblock)
{
int result;
result = ocf_metadata_raw_init(cache, lock_page_pfn, unlock_page_pfn, raw);
if (result)
return result;
segment->raw = raw;
segment->superblock = superblock;
return 0;
}
int ocf_metadata_segment_init(
struct ocf_metadata_segment **self,
struct ocf_cache *cache,
struct ocf_metadata_raw *raw,
ocf_flush_page_synch_t lock_page_pfn,
ocf_flush_page_synch_t unlock_page_pfn,
struct ocf_metadata_segment *superblock)
{
struct ocf_metadata_segment *segment;
int result;
segment = env_vzalloc(sizeof(*segment));
if (!segment)
return -OCF_ERR_NO_MEM;
result = ocf_metadata_segment_init_in_place(segment,
cache, raw, lock_page_pfn, unlock_page_pfn,
superblock);
if (result)
env_vfree(segment);
else
*self = segment;
return result;
}
void ocf_metadata_segment_destroy(struct ocf_cache *cache,
struct ocf_metadata_segment *self)
{
if (!self)
return;
ocf_metadata_raw_deinit(cache, self->raw);
env_vfree(self);
}
static void ocf_metadata_generic_complete(void *priv, int error)
{
@ -16,30 +75,32 @@ static void ocf_metadata_check_crc_skip(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg, bool skip_on_dirty_shutdown)
{
struct ocf_metadata_context *context = priv;
int segment = ocf_pipeline_arg_get_int(arg);
struct ocf_metadata_ctrl *ctrl;
struct ocf_superblock_config *sb_config;
int segment_id = ocf_pipeline_arg_get_int(arg);
struct ocf_metadata_segment *segment = context->ctrl->segment[segment_id];
ocf_cache_t cache = context->cache;
uint32_t crc;
uint32_t superblock_crc;
bool clean_shutdown;
ctrl = (struct ocf_metadata_ctrl *)cache->metadata.priv;
sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config);
if (!sb_config->clean_shutdown && skip_on_dirty_shutdown)
clean_shutdown = ocf_metadata_superblock_get_clean_shutdown(
segment->superblock);
if (!clean_shutdown && skip_on_dirty_shutdown)
OCF_PL_NEXT_RET(pipeline);
crc = ocf_metadata_raw_checksum(cache, &(ctrl->raw_desc[segment]));
crc = ocf_metadata_raw_checksum(cache, segment->raw);
superblock_crc = ocf_metadata_superblock_get_checksum(segment->superblock,
segment_id);
if (crc != sb_config->checksum[segment]) {
if (crc != superblock_crc) {
/* Checksum does not match */
if (!sb_config->clean_shutdown) {
if (!clean_shutdown) {
ocf_cache_log(cache, log_warn,
"Loading %s WARNING, invalid checksum",
ocf_metadata_segment_names[segment]);
ocf_metadata_segment_names[segment_id]);
} else {
ocf_cache_log(cache, log_err,
"Loading %s ERROR, invalid checksum",
ocf_metadata_segment_names[segment]);
ocf_metadata_segment_names[segment_id]);
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL);
}
}
@ -64,16 +125,11 @@ void ocf_metadata_calculate_crc(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_metadata_context *context = priv;
int segment = ocf_pipeline_arg_get_int(arg);
struct ocf_metadata_ctrl *ctrl;
struct ocf_superblock_config *sb_config;
ocf_cache_t cache = context->cache;
int segment_id = ocf_pipeline_arg_get_int(arg);
struct ocf_metadata_segment *segment = context->ctrl->segment[segment_id];
ctrl = (struct ocf_metadata_ctrl *)cache->metadata.priv;
sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config);
sb_config->checksum[segment] = ocf_metadata_raw_checksum(cache,
&(ctrl->raw_desc[segment]));
ocf_metadata_superblock_set_checksum(segment->superblock, segment_id,
ocf_metadata_raw_checksum(context->cache, segment->raw));
ocf_pipeline_next(pipeline);
}
@ -83,11 +139,9 @@ void ocf_metadata_flush_segment(ocf_pipeline_t pipeline,
{
struct ocf_metadata_context *context = priv;
int segment = ocf_pipeline_arg_get_int(arg);
struct ocf_metadata_ctrl *ctrl;
struct ocf_metadata_ctrl *ctrl = context->ctrl;
ocf_cache_t cache = context->cache;
ctrl = (struct ocf_metadata_ctrl *)cache->metadata.priv;
ocf_metadata_raw_flush_all(cache, &ctrl->raw_desc[segment],
ocf_metadata_generic_complete, context);
}
@ -97,11 +151,9 @@ void ocf_metadata_load_segment(ocf_pipeline_t pipeline,
{
struct ocf_metadata_context *context = priv;
int segment = ocf_pipeline_arg_get_int(arg);
struct ocf_metadata_ctrl *ctrl;
struct ocf_metadata_ctrl *ctrl = context->ctrl;
ocf_cache_t cache = context->cache;
ctrl = (struct ocf_metadata_ctrl *)cache->metadata.priv;
ocf_metadata_raw_load_all(cache, &ctrl->raw_desc[segment],
ocf_metadata_generic_complete, context);
}

View File

@ -9,6 +9,23 @@
#include "metadata_raw.h"
#include <ocf/ocf_def.h>
struct ocf_metadata_segment
{
struct ocf_metadata_raw *raw;
struct ocf_metadata_segment *superblock;
};
int ocf_metadata_segment_init(
struct ocf_metadata_segment **self,
struct ocf_cache *cache,
struct ocf_metadata_raw *raw,
ocf_flush_page_synch_t lock_page_pfn,
ocf_flush_page_synch_t unlock_page_pfn,
struct ocf_metadata_segment *superblock);
void ocf_metadata_segment_destroy(struct ocf_cache *cache,
struct ocf_metadata_segment *self);
void ocf_metadata_check_crc_if_clean(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg);

View File

@ -25,6 +25,13 @@
#define OCF_DEBUG_PARAM(cache, format, ...)
#endif
int ocf_metadata_segment_init_in_place(
struct ocf_metadata_segment *segment,
struct ocf_cache *cache,
struct ocf_metadata_raw *raw,
ocf_flush_page_synch_t lock_page_pfn,
ocf_flush_page_synch_t unlock_page_pfn,
struct ocf_metadata_segment *superblock);
/**
* @brief Super Block - Set Shutdown Status
@ -45,12 +52,14 @@ void ocf_metadata_set_shutdown_status(ocf_cache_t cache,
/*
* Get metadata hash service control structure
*/
/* TODO: get metadata ctrl from args rather than via cache */
ctrl = (struct ocf_metadata_ctrl *) cache->metadata.priv;
/*
* Get super block
*/
superblock = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config);
superblock = ocf_metadata_raw_get_mem(
&ctrl->raw_desc[metadata_segment_sb_config]);
/* Set shutdown status */
superblock->clean_shutdown = shutdown_status;
@ -271,7 +280,8 @@ void ocf_metadata_load_superblock(ocf_cache_t cache, ocf_metadata_end_t cmpl,
OCF_DEBUG_TRACE(cache);
ctrl = (struct ocf_metadata_ctrl *) cache->metadata.priv;
/* TODO: get ctrl from args rather than from cache */
ctrl = cache->metadata.priv;
ENV_BUG_ON(!ctrl);
sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config);
@ -291,6 +301,7 @@ void ocf_metadata_load_superblock(ocf_cache_t cache, ocf_metadata_end_t cmpl,
context->priv = priv;
context->pipeline = pipeline;
context->cache = cache;
context->ctrl = cache->metadata.priv;
ocf_pipeline_next(pipeline);
}
@ -318,9 +329,8 @@ static void ocf_metadata_calculate_crc_sb_config(ocf_pipeline_t pipeline,
struct ocf_metadata_context *context = priv;
struct ocf_metadata_ctrl *ctrl;
struct ocf_superblock_config *sb_config;
ocf_cache_t cache = context->cache;
ctrl = (struct ocf_metadata_ctrl *)cache->metadata.priv;
ctrl = context->ctrl;
sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config);
sb_config->checksum[metadata_segment_sb_config] = env_crc32(0,
@ -419,6 +429,77 @@ void ocf_metadata_flush_superblock(ocf_cache_t cache,
context->priv = priv;
context->pipeline = pipeline;
context->cache = cache;
context->ctrl = cache->metadata.priv;
ocf_pipeline_next(pipeline);
}
struct ocf_metadata_superblock
{
struct ocf_metadata_segment segment;
struct ocf_superblock_config *config;
};
#define _ocf_segment_to_sb(_segment) \
container_of(_segment, struct ocf_metadata_superblock, segment);
int ocf_metadata_superblock_init(
struct ocf_metadata_segment **self,
struct ocf_cache *cache,
struct ocf_metadata_raw *raw)
{
struct ocf_metadata_superblock *sb = env_vzalloc(sizeof(*sb));
int result;
if (!sb)
return -OCF_ERR_NO_MEM;
result = ocf_metadata_segment_init_in_place(&sb->segment, cache,
raw, NULL, NULL, &sb->segment);
if (result) {
env_vfree(sb);
return result;
}
sb->config = ocf_metadata_raw_get_mem(sb->segment.raw);
*self = &sb->segment;
return 0;
}
void ocf_metadata_superblock_destroy(
struct ocf_cache *cache,
struct ocf_metadata_segment *self)
{
ocf_metadata_segment_destroy(cache, self);
}
uint32_t ocf_metadata_superblock_get_checksum(
struct ocf_metadata_segment *self,
enum ocf_metadata_segment_id segment)
{
struct ocf_metadata_superblock *sb = _ocf_segment_to_sb(self);
return sb->config->checksum[segment];
}
void ocf_metadata_superblock_set_checksum(
struct ocf_metadata_segment *self,
enum ocf_metadata_segment_id segment,
uint32_t csum)
{
struct ocf_metadata_superblock *sb = _ocf_segment_to_sb(self);
sb->config->checksum[segment] = csum;
}
bool ocf_metadata_superblock_get_clean_shutdown(
struct ocf_metadata_segment *self)
{
struct ocf_metadata_superblock *sb = _ocf_segment_to_sb(self);
return sb->config->clean_shutdown;
}

View File

@ -64,6 +64,8 @@ struct ocf_superblock_runtime {
uint32_t cleaning_thread_access;
};
struct ocf_metadata_ctrl;
void ocf_metadata_set_shutdown_status(ocf_cache_t cache,
enum ocf_metadata_shutdown_status shutdown_status,
ocf_metadata_end_t cmpl, void *priv);
@ -74,4 +76,25 @@ void ocf_metadata_load_superblock(ocf_cache_t cache,
void ocf_metadata_flush_superblock(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);
int ocf_metadata_superblock_init(
struct ocf_metadata_segment **self,
struct ocf_cache *cache,
struct ocf_metadata_raw *raw);
void ocf_metadata_superblock_destroy(
struct ocf_cache *cache,
struct ocf_metadata_segment *self);
uint32_t ocf_metadata_superblock_get_checksum(
struct ocf_metadata_segment *self,
enum ocf_metadata_segment_id segment);
void ocf_metadata_superblock_set_checksum(
struct ocf_metadata_segment *self,
enum ocf_metadata_segment_id segment,
uint32_t csum);
bool ocf_metadata_superblock_get_clean_shutdown(
struct ocf_metadata_segment *self);
#endif /* METADATA_SUPERBLOCK_H_ */