Introduce flapping of metadata config sections
This feature provides double buffering of config sections to prevent situation when power failure during metadata flush leads to partially updated metadata. Flapping mechanism makes it always possible to perform graceful rollback to previous config metadata content in such situation. Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
parent
60218759d2
commit
99c8c05f3f
@ -187,6 +187,34 @@ static int64_t ocf_metadata_get_element_size(
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if particular metadata type supports flapping
|
||||
*/
|
||||
static bool ocf_metadata_is_flapped(
|
||||
enum ocf_metadata_segment_id type)
|
||||
{
|
||||
switch (type) {
|
||||
case metadata_segment_part_config:
|
||||
case metadata_segment_core_config:
|
||||
case metadata_segment_core_uuid:
|
||||
return true;
|
||||
|
||||
case metadata_segment_sb_config:
|
||||
case metadata_segment_sb_runtime:
|
||||
case metadata_segment_reserved:
|
||||
case metadata_segment_part_runtime:
|
||||
case metadata_segment_core_runtime:
|
||||
case metadata_segment_cleaning:
|
||||
case metadata_segment_lru:
|
||||
case metadata_segment_collision:
|
||||
case metadata_segment_list_info:
|
||||
case metadata_segment_hash:
|
||||
default:
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Metadata calculation exception handling.
|
||||
*
|
||||
@ -484,6 +512,9 @@ static struct ocf_metadata_ctrl *ocf_metadata_ctrl_init(
|
||||
= ocf_metadata_get_element_size(i, 0);
|
||||
raw->entries_in_page = PAGE_SIZE / raw->entry_size;
|
||||
|
||||
/* Setup flapping support */
|
||||
raw->flapping = ocf_metadata_is_flapped(i);
|
||||
|
||||
/* Setup number of entries */
|
||||
raw->entries = ocf_metadata_get_entries(i, 0);
|
||||
|
||||
@ -675,6 +706,9 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache,
|
||||
raw->entry_size
|
||||
= ocf_metadata_get_element_size(i, line_size);
|
||||
raw->entries_in_page = PAGE_SIZE / raw->entry_size;
|
||||
|
||||
/* Setup flapping support */
|
||||
raw->flapping = ocf_metadata_is_flapped(i);
|
||||
}
|
||||
|
||||
if (0 != ocf_metadata_calculate_metadata_size(cache, ctrl, line_size)) {
|
||||
@ -1009,7 +1043,7 @@ void ocf_metadata_flush_collision(ocf_cache_t cache,
|
||||
ctrl = cache->metadata.priv;
|
||||
raw = &ctrl->raw_desc[metadata_segment_collision];
|
||||
|
||||
ocf_metadata_raw_flush_all(cache, raw, cmpl, priv);
|
||||
ocf_metadata_raw_flush_all(cache, raw, cmpl, priv, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -33,13 +33,24 @@
|
||||
/*******************************************************************************
|
||||
* Common RAW Implementation
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t _raw_ram_segment_size_on_ssd(struct ocf_metadata_raw *raw)
|
||||
{
|
||||
const size_t alignment = 128 * KiB / PAGE_SIZE;
|
||||
|
||||
return OCF_DIV_ROUND_UP(raw->ssd_pages, alignment) * alignment;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if page is valid for specified RAW descriptor
|
||||
*/
|
||||
static bool _raw_ssd_page_is_valid(struct ocf_metadata_raw *raw, uint32_t page)
|
||||
{
|
||||
uint32_t size = _raw_ram_segment_size_on_ssd(raw) *
|
||||
(raw->flapping ? 2 : 1);
|
||||
|
||||
ENV_BUG_ON(page < raw->ssd_pages_offset);
|
||||
ENV_BUG_ON(page >= (raw->ssd_pages_offset + raw->ssd_pages));
|
||||
ENV_BUG_ON(page >= (raw->ssd_pages_offset + size));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -144,9 +155,9 @@ static size_t _raw_ram_size_of(ocf_cache_t cache, struct ocf_metadata_raw *raw)
|
||||
*/
|
||||
static uint32_t _raw_ram_size_on_ssd(struct ocf_metadata_raw *raw)
|
||||
{
|
||||
const size_t alignment = 128 * KiB / PAGE_SIZE;
|
||||
size_t flapping_factor = raw->flapping ? 2 : 1;
|
||||
|
||||
return OCF_DIV_ROUND_UP(raw->ssd_pages, alignment) * alignment;
|
||||
return _raw_ram_segment_size_on_ssd(raw) * flapping_factor;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -226,6 +237,7 @@ static int _raw_ram_update(ocf_cache_t cache,
|
||||
|
||||
struct _raw_ram_load_all_context {
|
||||
struct ocf_metadata_raw *raw;
|
||||
uint64_t ssd_pages_offset;
|
||||
ocf_metadata_end_t cmpl;
|
||||
void *priv;
|
||||
};
|
||||
@ -240,7 +252,7 @@ static int _raw_ram_load_all_drain(ocf_cache_t cache,
|
||||
struct ocf_metadata_raw *raw = context->raw;
|
||||
|
||||
return _raw_ram_drain_page(cache, raw, data,
|
||||
page - raw->ssd_pages_offset);
|
||||
page - context->ssd_pages_offset);
|
||||
}
|
||||
|
||||
static void _raw_ram_load_all_complete(ocf_cache_t cache,
|
||||
@ -256,11 +268,12 @@ static void _raw_ram_load_all_complete(ocf_cache_t cache,
|
||||
* RAM Implementation - Load all metadata elements from SSD
|
||||
*/
|
||||
static void _raw_ram_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv)
|
||||
ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx)
|
||||
{
|
||||
struct _raw_ram_load_all_context *context;
|
||||
int result;
|
||||
|
||||
ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0);
|
||||
OCF_DEBUG_TRACE(cache);
|
||||
|
||||
context = env_vmalloc(sizeof(*context));
|
||||
@ -270,9 +283,11 @@ static void _raw_ram_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
context->raw = raw;
|
||||
context->cmpl = cmpl;
|
||||
context->priv = priv;
|
||||
context->ssd_pages_offset = raw->ssd_pages_offset +
|
||||
_raw_ram_segment_size_on_ssd(raw) * flapping_idx;
|
||||
|
||||
result = metadata_io_read_i_asynch(cache, cache->mngt_queue, context,
|
||||
raw->ssd_pages_offset, raw->ssd_pages, 0,
|
||||
context->ssd_pages_offset, raw->ssd_pages, 0,
|
||||
_raw_ram_load_all_drain, _raw_ram_load_all_complete);
|
||||
if (result)
|
||||
_raw_ram_load_all_complete(cache, context, result);
|
||||
@ -280,6 +295,7 @@ static void _raw_ram_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
|
||||
struct _raw_ram_flush_all_context {
|
||||
struct ocf_metadata_raw *raw;
|
||||
uint64_t ssd_pages_offset;
|
||||
ocf_metadata_end_t cmpl;
|
||||
void *priv;
|
||||
};
|
||||
@ -299,7 +315,7 @@ static int _raw_ram_flush_all_fill(ocf_cache_t cache,
|
||||
ENV_BUG_ON(!_raw_ssd_page_is_valid(raw, page));
|
||||
ENV_BUG_ON(size > PAGE_SIZE);
|
||||
|
||||
raw_page = page - raw->ssd_pages_offset;
|
||||
raw_page = page - context->ssd_pages_offset;
|
||||
line = raw_page * raw->entries_in_page;
|
||||
|
||||
OCF_DEBUG_PARAM(cache, "Line = %u, Page = %u", line, raw_page);
|
||||
@ -328,11 +344,11 @@ static void _raw_ram_flush_all_complete(ocf_cache_t cache,
|
||||
* RAM Implementation - Flush all elements
|
||||
*/
|
||||
static void _raw_ram_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv)
|
||||
ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx)
|
||||
{
|
||||
struct _raw_ram_flush_all_context *context;
|
||||
int result;
|
||||
|
||||
ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0);
|
||||
OCF_DEBUG_TRACE(cache);
|
||||
|
||||
context = env_vmalloc(sizeof(*context));
|
||||
@ -342,9 +358,11 @@ static void _raw_ram_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
context->raw = raw;
|
||||
context->cmpl = cmpl;
|
||||
context->priv = priv;
|
||||
context->ssd_pages_offset = raw->ssd_pages_offset +
|
||||
_raw_ram_segment_size_on_ssd(raw) * flapping_idx;
|
||||
|
||||
result = metadata_io_write_i_asynch(cache, cache->mngt_queue, context,
|
||||
raw->ssd_pages_offset, raw->ssd_pages, 0,
|
||||
context->ssd_pages_offset, raw->ssd_pages, 0,
|
||||
_raw_ram_flush_all_fill, _raw_ram_flush_all_complete,
|
||||
raw->mio_conc);
|
||||
if (result)
|
||||
|
@ -69,6 +69,7 @@ struct ocf_metadata_raw {
|
||||
uint32_t entry_size; /*!< Size of particular entry */
|
||||
uint32_t entries_in_page; /*!< Numbers of entries in one page*/
|
||||
uint64_t entries; /*!< Numbers of entries */
|
||||
bool flapping; /* !< Supports flapping */
|
||||
|
||||
/**
|
||||
* @name Location on cache device description
|
||||
@ -129,10 +130,12 @@ struct raw_iface {
|
||||
ctx_data_t *data, uint64_t page, uint64_t count);
|
||||
|
||||
void (*load_all)(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv);
|
||||
ocf_metadata_end_t cmpl, void *priv,
|
||||
unsigned flapping_idx);
|
||||
|
||||
void (*flush_all)(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv);
|
||||
ocf_metadata_end_t cmpl, void *priv,
|
||||
unsigned flapping_idx);
|
||||
|
||||
void (*flush_mark)(ocf_cache_t cache, struct ocf_request *req,
|
||||
uint32_t map_idx, int to_state, uint8_t start,
|
||||
@ -269,12 +272,13 @@ static inline int ocf_metadata_raw_update(ocf_cache_t cache,
|
||||
* @param raw - RAW descriptor
|
||||
* @param cmpl - Completion callback
|
||||
* @param priv - Completion callback context
|
||||
* @param flapping_idx - Index of flapping segment version
|
||||
*/
|
||||
static inline void ocf_metadata_raw_load_all(ocf_cache_t cache,
|
||||
struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv)
|
||||
struct ocf_metadata_raw *raw, ocf_metadata_end_t cmpl,
|
||||
void *priv, unsigned flapping_idx)
|
||||
{
|
||||
raw->iface->load_all(cache, raw, cmpl, priv);
|
||||
raw->iface->load_all(cache, raw, cmpl, priv, flapping_idx);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -284,12 +288,13 @@ static inline void ocf_metadata_raw_load_all(ocf_cache_t cache,
|
||||
* @param raw - RAW descriptor
|
||||
* @param cmpl - Completion callback
|
||||
* @param priv - Completion callback context
|
||||
* @param flapping_idx - Index of flapping segment version
|
||||
*/
|
||||
static inline void ocf_metadata_raw_flush_all(ocf_cache_t cache,
|
||||
struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv)
|
||||
struct ocf_metadata_raw *raw, ocf_metadata_end_t cmpl,
|
||||
void *priv, unsigned flapping_idx)
|
||||
{
|
||||
raw->iface->flush_all(cache, raw, cmpl, priv);
|
||||
raw->iface->flush_all(cache, raw, cmpl, priv, flapping_idx);
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,10 +36,21 @@
|
||||
/*
|
||||
* Check if page is valid for specified RAW descriptor
|
||||
*/
|
||||
|
||||
uint32_t raw_dynamic_segment_size_on_ssd(struct ocf_metadata_raw *raw)
|
||||
{
|
||||
const size_t alignment = 128 * KiB / PAGE_SIZE;
|
||||
|
||||
return OCF_DIV_ROUND_UP(raw->ssd_pages, alignment) * alignment;
|
||||
}
|
||||
|
||||
static bool _raw_ssd_page_is_valid(struct ocf_metadata_raw *raw, uint32_t page)
|
||||
{
|
||||
uint32_t size = raw_dynamic_segment_size_on_ssd(raw) *
|
||||
(raw->flapping ? 2 : 1);
|
||||
|
||||
ENV_BUG_ON(page < raw->ssd_pages_offset);
|
||||
ENV_BUG_ON(page >= (raw->ssd_pages_offset + raw->ssd_pages));
|
||||
ENV_BUG_ON(page >= (raw->ssd_pages_offset + size));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -212,9 +223,9 @@ size_t raw_dynamic_size_of(ocf_cache_t cache,
|
||||
*/
|
||||
uint32_t raw_dynamic_size_on_ssd(struct ocf_metadata_raw *raw)
|
||||
{
|
||||
const size_t alignment = 128 * KiB / PAGE_SIZE;
|
||||
size_t flapping_factor = raw->flapping ? 2 : 1;
|
||||
|
||||
return OCF_DIV_ROUND_UP(raw->ssd_pages, alignment) * alignment;
|
||||
return raw_dynamic_segment_size_on_ssd(raw) * flapping_factor;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -337,6 +348,7 @@ int raw_dynamic_update(ocf_cache_t cache,
|
||||
|
||||
struct raw_dynamic_load_all_context {
|
||||
struct ocf_metadata_raw *raw;
|
||||
unsigned flapping_idx;
|
||||
struct ocf_request *req;
|
||||
ocf_cache_t cache;
|
||||
struct ocf_io *io;
|
||||
@ -388,14 +400,19 @@ static int raw_dynamic_load_all_read(struct ocf_request *req)
|
||||
{
|
||||
struct raw_dynamic_load_all_context *context = req->priv;
|
||||
struct ocf_metadata_raw *raw = context->raw;
|
||||
uint64_t ssd_pages_offset;
|
||||
uint64_t count;
|
||||
int result;
|
||||
|
||||
ssd_pages_offset = raw->ssd_pages_offset +
|
||||
raw_dynamic_segment_size_on_ssd(raw) *
|
||||
context->flapping_idx;
|
||||
|
||||
count = metadata_io_size(context->i_page, raw->ssd_pages);
|
||||
|
||||
/* Allocate IO */
|
||||
context->io = ocf_new_cache_io(context->cache, req->io_queue,
|
||||
PAGES_TO_BYTES(raw->ssd_pages_offset + context->i_page),
|
||||
PAGES_TO_BYTES(ssd_pages_offset + context->i_page),
|
||||
PAGES_TO_BYTES(count), OCF_READ, 0, 0);
|
||||
|
||||
if (!context->io) {
|
||||
@ -453,11 +470,12 @@ static int raw_dynamic_load_all_update(struct ocf_request *req)
|
||||
}
|
||||
|
||||
void raw_dynamic_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv)
|
||||
ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx)
|
||||
{
|
||||
struct raw_dynamic_load_all_context *context;
|
||||
int result;
|
||||
|
||||
ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0);
|
||||
OCF_DEBUG_TRACE(cache);
|
||||
|
||||
context = env_vzalloc(sizeof(*context));
|
||||
@ -465,6 +483,7 @@ void raw_dynamic_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
OCF_CMPL_RET(priv, -OCF_ERR_NO_MEM);
|
||||
|
||||
context->raw = raw;
|
||||
context->flapping_idx = flapping_idx;
|
||||
context->cache = cache;
|
||||
context->cmpl = cmpl;
|
||||
context->priv = priv;
|
||||
@ -509,6 +528,7 @@ err_data:
|
||||
|
||||
struct raw_dynamic_flush_all_context {
|
||||
struct ocf_metadata_raw *raw;
|
||||
uint64_t ssd_pages_offset;
|
||||
ocf_metadata_end_t cmpl;
|
||||
void *priv;
|
||||
};
|
||||
@ -526,7 +546,7 @@ static int raw_dynamic_flush_all_fill(ocf_cache_t cache,
|
||||
|
||||
ENV_BUG_ON(!_raw_ssd_page_is_valid(raw, page));
|
||||
|
||||
raw_page = page - raw->ssd_pages_offset;
|
||||
raw_page = page - context->ssd_pages_offset;
|
||||
|
||||
if (ctrl->pages[raw_page]) {
|
||||
OCF_DEBUG_PARAM(cache, "Page = %u", raw_page);
|
||||
@ -555,11 +575,12 @@ static void raw_dynamic_flush_all_complete(ocf_cache_t cache,
|
||||
}
|
||||
|
||||
void raw_dynamic_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv)
|
||||
ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx)
|
||||
{
|
||||
struct raw_dynamic_flush_all_context *context;
|
||||
int result;
|
||||
|
||||
ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0);
|
||||
OCF_DEBUG_TRACE(cache);
|
||||
|
||||
context = env_vmalloc(sizeof(*context));
|
||||
@ -569,9 +590,11 @@ void raw_dynamic_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
context->raw = raw;
|
||||
context->cmpl = cmpl;
|
||||
context->priv = priv;
|
||||
context->ssd_pages_offset = raw->ssd_pages_offset +
|
||||
raw_dynamic_segment_size_on_ssd(raw) * flapping_idx;
|
||||
|
||||
result = metadata_io_write_i_asynch(cache, cache->mngt_queue, context,
|
||||
raw->ssd_pages_offset, raw->ssd_pages, 0,
|
||||
context->ssd_pages_offset, raw->ssd_pages, 0,
|
||||
raw_dynamic_flush_all_fill,
|
||||
raw_dynamic_flush_all_complete,
|
||||
raw->mio_conc);
|
||||
|
@ -65,14 +65,14 @@ int raw_dynamic_update(ocf_cache_t cache,
|
||||
* from cache device
|
||||
*/
|
||||
void raw_dynamic_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv);
|
||||
ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx);
|
||||
|
||||
/*
|
||||
* RAW DYNAMIC - Flush all metadata of this RAW metadata container
|
||||
* to cache device
|
||||
*/
|
||||
void raw_dynamic_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv);
|
||||
ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx);
|
||||
|
||||
/*
|
||||
* RAW DYNAMIC - Mark specified entry to be flushed
|
||||
|
@ -41,7 +41,7 @@ int raw_volatile_update(ocf_cache_t cache,
|
||||
* RAW volatile Implementation - Load all metadata elements from SSD
|
||||
*/
|
||||
void raw_volatile_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv)
|
||||
ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx)
|
||||
{
|
||||
cmpl(priv, -OCF_ERR_NOT_SUPP);
|
||||
}
|
||||
@ -50,7 +50,7 @@ void raw_volatile_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
* RAM Implementation - Flush all elements
|
||||
*/
|
||||
void raw_volatile_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv)
|
||||
ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx)
|
||||
{
|
||||
cmpl(priv, 0);
|
||||
}
|
||||
|
@ -28,13 +28,13 @@ int raw_volatile_update(ocf_cache_t cache,
|
||||
* RAW volatile Implementation - Load all metadata elements from SSD
|
||||
*/
|
||||
void raw_volatile_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv);
|
||||
ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx);
|
||||
|
||||
/*
|
||||
* RAW volatile Implementation - Flush all elements
|
||||
*/
|
||||
void raw_volatile_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw,
|
||||
ocf_metadata_end_t cmpl, void *priv);
|
||||
ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx);
|
||||
|
||||
/*
|
||||
* RAM RAW volatile Implementation - Mark to Flush
|
||||
|
@ -138,22 +138,32 @@ void ocf_metadata_flush_segment(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 = context->ctrl;
|
||||
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;
|
||||
unsigned next_flapping_idx =
|
||||
ocf_metadata_superblock_get_next_flapping_idx(
|
||||
segment->superblock);
|
||||
|
||||
ocf_metadata_raw_flush_all(cache, &ctrl->raw_desc[segment],
|
||||
ocf_metadata_generic_complete, context);
|
||||
next_flapping_idx = segment->raw->flapping ? next_flapping_idx : 0;
|
||||
|
||||
ocf_metadata_raw_flush_all(cache, segment->raw,
|
||||
ocf_metadata_generic_complete, context,
|
||||
next_flapping_idx);
|
||||
}
|
||||
|
||||
void ocf_metadata_load_segment(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 = context->ctrl;
|
||||
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;
|
||||
unsigned flapping_idx = ocf_metadata_superblock_get_flapping_idx(
|
||||
segment->superblock);
|
||||
|
||||
ocf_metadata_raw_load_all(cache, &ctrl->raw_desc[segment],
|
||||
ocf_metadata_generic_complete, context);
|
||||
flapping_idx = segment->raw->flapping ? flapping_idx : 0;
|
||||
|
||||
ocf_metadata_raw_load_all(cache, segment->raw,
|
||||
ocf_metadata_generic_complete, context, flapping_idx);
|
||||
}
|
||||
|
@ -325,11 +325,21 @@ static void ocf_metadata_flush_superblock_finish(ocf_pipeline_t pipeline,
|
||||
void *priv, int error)
|
||||
{
|
||||
struct ocf_metadata_context *context = priv;
|
||||
struct ocf_metadata_ctrl *ctrl;
|
||||
struct ocf_superblock_config *sb_config;
|
||||
ocf_cache_t cache = context->cache;
|
||||
|
||||
if (error)
|
||||
if (error) {
|
||||
ocf_metadata_error(cache);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ctrl = context->ctrl;
|
||||
sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config);
|
||||
|
||||
sb_config->flapping_idx = (sb_config->flapping_idx + 1) % 2;
|
||||
|
||||
end:
|
||||
context->cmpl(context->priv, error);
|
||||
ocf_pipeline_destroy(pipeline);
|
||||
}
|
||||
@ -357,15 +367,7 @@ static void ocf_metadata_flush_disk(ocf_pipeline_t pipeline,
|
||||
ocf_metadata_flush_disk_end, context);
|
||||
}
|
||||
|
||||
struct ocf_pipeline_arg ocf_metadata_flush_sb_calculate_crc_args[] = {
|
||||
OCF_PL_ARG_INT(metadata_segment_part_config),
|
||||
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_flush_sb_flush_segment_args[] = {
|
||||
OCF_PL_ARG_INT(metadata_segment_sb_config),
|
||||
struct ocf_pipeline_arg ocf_metadata_flush_sb_args[] = {
|
||||
OCF_PL_ARG_INT(metadata_segment_part_config),
|
||||
OCF_PL_ARG_INT(metadata_segment_core_config),
|
||||
OCF_PL_ARG_INT(metadata_segment_core_uuid),
|
||||
@ -379,9 +381,12 @@ struct ocf_pipeline_properties ocf_metadata_flush_sb_pipeline_props = {
|
||||
OCF_PL_STEP(ocf_metadata_flush_superblock_prepare),
|
||||
OCF_PL_STEP(ocf_metadata_calculate_crc_sb_config),
|
||||
OCF_PL_STEP_FOREACH(ocf_metadata_calculate_crc,
|
||||
ocf_metadata_flush_sb_calculate_crc_args),
|
||||
ocf_metadata_flush_sb_args),
|
||||
OCF_PL_STEP_FOREACH(ocf_metadata_flush_segment,
|
||||
ocf_metadata_flush_sb_flush_segment_args),
|
||||
ocf_metadata_flush_sb_args),
|
||||
OCF_PL_STEP(ocf_metadata_flush_disk),
|
||||
OCF_PL_STEP_ARG_INT(ocf_metadata_flush_segment,
|
||||
metadata_segment_sb_config),
|
||||
OCF_PL_STEP(ocf_metadata_flush_disk),
|
||||
OCF_PL_STEP_TERMINATOR(),
|
||||
},
|
||||
@ -484,6 +489,22 @@ bool ocf_metadata_superblock_get_clean_shutdown(
|
||||
return sb->config->clean_shutdown;
|
||||
}
|
||||
|
||||
unsigned ocf_metadata_superblock_get_flapping_idx(
|
||||
struct ocf_metadata_segment *self)
|
||||
{
|
||||
struct ocf_metadata_superblock *sb = _ocf_segment_to_sb(self);
|
||||
|
||||
return sb->config->flapping_idx;
|
||||
}
|
||||
|
||||
unsigned ocf_metadata_superblock_get_next_flapping_idx(
|
||||
struct ocf_metadata_segment *self)
|
||||
{
|
||||
struct ocf_metadata_superblock *sb = _ocf_segment_to_sb(self);
|
||||
|
||||
return (sb->config->flapping_idx + 1) % 2;
|
||||
}
|
||||
|
||||
int ocf_metadata_validate_superblock(ocf_ctx_t ctx,
|
||||
struct ocf_superblock_config *superblock)
|
||||
{
|
||||
|
@ -29,6 +29,8 @@ struct ocf_superblock_config {
|
||||
|
||||
uint32_t metadata_version;
|
||||
|
||||
unsigned flapping_idx;
|
||||
|
||||
/* Currently set cache mode */
|
||||
ocf_cache_mode_t cache_mode;
|
||||
|
||||
@ -97,6 +99,12 @@ void ocf_metadata_superblock_set_checksum(
|
||||
bool ocf_metadata_superblock_get_clean_shutdown(
|
||||
struct ocf_metadata_segment *self);
|
||||
|
||||
unsigned ocf_metadata_superblock_get_flapping_idx(
|
||||
struct ocf_metadata_segment *self);
|
||||
|
||||
unsigned ocf_metadata_superblock_get_next_flapping_idx(
|
||||
struct ocf_metadata_segment *self);
|
||||
|
||||
int ocf_metadata_validate_superblock(ocf_ctx_t ctx,
|
||||
struct ocf_superblock_config *superblock);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user