Merge pull request #422 from arutk/light_meta

reduce metadata interface overhead
This commit is contained in:
Robert Baldyga 2020-12-21 14:34:37 +01:00 committed by GitHub
commit 0964e0e9df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 3245 additions and 3720 deletions

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
#include "metadata_cleaning_policy.h" #include "metadata_cleaning_policy.h"
#include "metadata_eviction_policy.h" #include "metadata_eviction_policy.h"
#include "metadata_partition.h" #include "metadata_partition.h"
#include "metadata_hash.h" #include "metadata_segment_id.h"
#include "metadata_superblock.h" #include "metadata_superblock.h"
#include "metadata_status.h" #include "metadata_status.h"
#include "metadata_collision.h" #include "metadata_collision.h"
@ -170,10 +170,7 @@ void ocf_metadata_load_recovery(ocf_cache_t cache,
* *
* @param cache Cache instance * @param cache Cache instance
*/ */
static inline uint64_t ocf_metadata_get_reserved_lba(ocf_cache_t cache) uint64_t ocf_metadata_get_reserved_lba(ocf_cache_t cache);
{
return cache->metadata.iface.get_reserved_lba(cache);
}
/* /*
* NOTE Hash table is specific for hash table metadata service implementation * NOTE Hash table is specific for hash table metadata service implementation
@ -182,23 +179,11 @@ static inline uint64_t ocf_metadata_get_reserved_lba(ocf_cache_t cache)
* temporary defined in this file. * temporary defined in this file.
*/ */
static inline ocf_cache_line_t ocf_cache_line_t
ocf_metadata_get_hash(struct ocf_cache *cache, ocf_cache_line_t index) ocf_metadata_get_hash(struct ocf_cache *cache, ocf_cache_line_t index);
{
return cache->metadata.iface.get_hash(cache, index);
}
static inline void ocf_metadata_set_hash(struct ocf_cache *cache, void ocf_metadata_set_hash(struct ocf_cache *cache,
ocf_cache_line_t index, ocf_cache_line_t line) ocf_cache_line_t index, ocf_cache_line_t line);
{
cache->metadata.iface.set_hash(cache, index, line);
}
static inline ocf_cache_line_t ocf_metadata_entries_hash(
struct ocf_cache *cache)
{
return cache->metadata.iface.entries_hash(cache);
}
struct ocf_metadata_load_properties { struct ocf_metadata_load_properties {
enum ocf_metadata_shutdown_status shutdown_status; enum ocf_metadata_shutdown_status shutdown_status;

View File

@ -57,8 +57,8 @@ static bool _ocf_metadata_test_##what##_##type(struct ocf_cache *cache, \
{ \ { \
type mask = _get_mask_##type(start, stop); \ type mask = _get_mask_##type(start, stop); \
\ \
struct ocf_metadata_hash_ctrl *ctrl = \ struct ocf_metadata_ctrl *ctrl = \
(struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ (struct ocf_metadata_ctrl *) cache->metadata.priv; \
\ \
struct ocf_metadata_raw *raw = \ struct ocf_metadata_raw *raw = \
&ctrl->raw_desc[metadata_segment_collision]; \ &ctrl->raw_desc[metadata_segment_collision]; \
@ -87,8 +87,8 @@ static bool _ocf_metadata_test_out_##what##_##type(struct ocf_cache *cache, \
{ \ { \
type mask = _get_mask_##type(start, stop); \ type mask = _get_mask_##type(start, stop); \
\ \
struct ocf_metadata_hash_ctrl *ctrl = \ struct ocf_metadata_ctrl *ctrl = \
(struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ (struct ocf_metadata_ctrl *) cache->metadata.priv; \
\ \
struct ocf_metadata_raw *raw = \ struct ocf_metadata_raw *raw = \
&ctrl->raw_desc[metadata_segment_collision]; \ &ctrl->raw_desc[metadata_segment_collision]; \
@ -109,8 +109,8 @@ static bool _ocf_metadata_clear_##what##_##type(struct ocf_cache *cache, \
{ \ { \
type mask = _get_mask_##type(start, stop); \ type mask = _get_mask_##type(start, stop); \
\ \
struct ocf_metadata_hash_ctrl *ctrl = \ struct ocf_metadata_ctrl *ctrl = \
(struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ (struct ocf_metadata_ctrl *) cache->metadata.priv; \
\ \
struct ocf_metadata_raw *raw = \ struct ocf_metadata_raw *raw = \
&ctrl->raw_desc[metadata_segment_collision]; \ &ctrl->raw_desc[metadata_segment_collision]; \
@ -134,8 +134,8 @@ static bool _ocf_metadata_set_##what##_##type(struct ocf_cache *cache, \
bool result; \ bool result; \
type mask = _get_mask_##type(start, stop); \ type mask = _get_mask_##type(start, stop); \
\ \
struct ocf_metadata_hash_ctrl *ctrl = \ struct ocf_metadata_ctrl *ctrl = \
(struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ (struct ocf_metadata_ctrl *) cache->metadata.priv; \
\ \
struct ocf_metadata_raw *raw = \ struct ocf_metadata_raw *raw = \
&ctrl->raw_desc[metadata_segment_collision]; \ &ctrl->raw_desc[metadata_segment_collision]; \
@ -158,8 +158,8 @@ static bool _ocf_metadata_test_and_set_##what##_##type( \
bool test; \ bool test; \
type mask = _get_mask_##type(start, stop); \ type mask = _get_mask_##type(start, stop); \
\ \
struct ocf_metadata_hash_ctrl *ctrl = \ struct ocf_metadata_ctrl *ctrl = \
(struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ (struct ocf_metadata_ctrl *) cache->metadata.priv; \
\ \
struct ocf_metadata_raw *raw = \ struct ocf_metadata_raw *raw = \
&ctrl->raw_desc[metadata_segment_collision]; \ &ctrl->raw_desc[metadata_segment_collision]; \
@ -193,8 +193,8 @@ static bool _ocf_metadata_test_and_clear_##what##_##type( \
bool test; \ bool test; \
type mask = _get_mask_##type(start, stop); \ type mask = _get_mask_##type(start, stop); \
\ \
struct ocf_metadata_hash_ctrl *ctrl = \ struct ocf_metadata_ctrl *ctrl = \
(struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ (struct ocf_metadata_ctrl *) cache->metadata.priv; \
\ \
struct ocf_metadata_raw *raw = \ struct ocf_metadata_raw *raw = \
&ctrl->raw_desc[metadata_segment_collision]; \ &ctrl->raw_desc[metadata_segment_collision]; \

View File

@ -0,0 +1,23 @@
/*
* copyright(c) 2020 intel corporation
* spdx-license-identifier: bsd-3-clause-clear
*/
#include "ocf/ocf.h"
#include "metadata.h"
#include "metadata_cleaning_policy.h"
#include "metadata_internal.h"
/*
* Cleaning policy - Get
*/
struct cleaning_policy_meta *
ocf_metadata_get_cleaning_policy(struct ocf_cache *cache,
ocf_cache_line_t line)
{
struct ocf_metadata_ctrl *ctrl
= (struct ocf_metadata_ctrl *) cache->metadata.priv;
return ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_cleaning]), line);
}

View File

@ -6,12 +6,9 @@
#ifndef __METADATA_CLEANING_POLICY_H__ #ifndef __METADATA_CLEANING_POLICY_H__
#define __METADATA_CLEANING_POLICY_H__ #define __METADATA_CLEANING_POLICY_H__
static inline struct cleaning_policy_meta * struct cleaning_policy_meta *
ocf_metadata_get_cleaning_policy(struct ocf_cache *cache, ocf_metadata_get_cleaning_policy(struct ocf_cache *cache,
ocf_cache_line_t line) ocf_cache_line_t line);
{
return cache->metadata.iface.get_cleaning_policy(cache, line);
}
#endif /* METADATA_CLEANING_POLICY_H_ */ #endif /* METADATA_CLEANING_POLICY_H_ */

View File

@ -5,8 +5,225 @@
#include "ocf/ocf.h" #include "ocf/ocf.h"
#include "metadata.h" #include "metadata.h"
#include "metadata_internal.h"
#include "../utils/utils_cache_line.h" #include "../utils/utils_cache_line.h"
static ocf_cache_line_t ocf_metadata_map_lg2phy_seq(
struct ocf_cache *cache, ocf_cache_line_t coll_idx)
{
return coll_idx;
}
static ocf_cache_line_t ocf_metadata_map_phy2lg_seq(
struct ocf_cache *cache, ocf_cache_line_t cache_line)
{
return cache_line;
}
/**
* This function is mapping collision index to appropriate cache line
* (logical cache line to physical one mapping).
*
* It is necessary because we want to generate sequential workload with
* data to cache device.
* Our collision list, for example, looks:
* 0 3 6 9
* 1 4 7 10
* 2 5 8
* All collision index in each column is on the same page
* on cache device. We don't want send request x times to the same
* page. To don't do it we use collision index by row, but in this
* case we can't use collision index directly as cache line,
* because we will generate non sequential workload (we will write
* pages: 0 -> 3 -> 6 ...). To map collision index in correct way
* we use this function.
*
* After use this function, collision index in the above array
* corresponds with below cache line:
* 0 1 2 3
* 4 5 6 7
* 8 9 10
*
* @param cache - cache instance
* @param idx - index in collision list
* @return mapped cache line
*/static ocf_cache_line_t ocf_metadata_map_lg2phy_striping(
struct ocf_cache *cache, ocf_cache_line_t coll_idx)
{
ocf_cache_line_t cache_line = 0, offset = 0;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
unsigned int entries_in_page =
ctrl->raw_desc[metadata_segment_collision].entries_in_page;
unsigned int pages =
ctrl->raw_desc[metadata_segment_collision].ssd_pages;
ocf_cache_line_t collision_table_entries =
cache->device->collision_table_entries;
ocf_cache_line_t delta =
(entries_in_page * pages) - collision_table_entries;
unsigned int row = coll_idx % entries_in_page;
if (row > entries_in_page - delta)
offset = row - (entries_in_page - delta);
else
offset = 0;
cache_line = (row * pages) + (coll_idx / entries_in_page) - offset;
return cache_line;
}
/**
* @brief Map physical cache line on cache device to logical one
* @note This function is the inverse of map_coll_idx_to_cache_line
*
* @param cache Cache instance
* @param phy Physical cache line of cache device
* @return Logical cache line
*/
static ocf_cache_line_t ocf_metadata_map_phy2lg_striping(
struct ocf_cache *cache, ocf_cache_line_t cache_line)
{
ocf_cache_line_t coll_idx = 0;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
struct ocf_metadata_raw *raw =
&ctrl->raw_desc[metadata_segment_collision];
unsigned int pages = raw->ssd_pages;
unsigned int entries_in_page = raw->entries_in_page;
unsigned int entries_in_last_page = raw->entries % entries_in_page ?:
entries_in_page;
unsigned int row = 0, coll = 0;
unsigned int last = entries_in_last_page * pages;
if (cache_line < last) {
row = cache_line % pages;
coll = cache_line / pages;
} else {
cache_line -= last;
row = cache_line % (pages - 1);
coll = cache_line / (pages - 1) + entries_in_last_page;
}
coll_idx = (row * entries_in_page) + coll;
return coll_idx;
}
ocf_cache_line_t ocf_metadata_map_lg2phy(
struct ocf_cache *cache, ocf_cache_line_t coll_idx)
{
switch (cache->metadata.layout) {
case ocf_metadata_layout_striping:
return ocf_metadata_map_lg2phy_striping(
cache, coll_idx);
case ocf_metadata_layout_seq:
return ocf_metadata_map_lg2phy_seq(
cache, coll_idx);
default:
ENV_BUG();
return 0;
}
}
ocf_cache_line_t ocf_metadata_map_phy2lg(
struct ocf_cache *cache, ocf_cache_line_t cache_line)
{
switch (cache->metadata.layout) {
case ocf_metadata_layout_striping:
return ocf_metadata_map_phy2lg_striping(
cache, cache_line);
case ocf_metadata_layout_seq:
return ocf_metadata_map_phy2lg_seq(
cache, cache_line);
default:
ENV_BUG();
return 0;
}
}
void ocf_metadata_set_collision_info(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t next,
ocf_cache_line_t prev)
{
struct ocf_metadata_list_info *info;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
info = ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
if (info) {
info->next_col = next;
info->prev_col = prev;
} else {
ocf_metadata_error(cache);
}
}
void ocf_metadata_set_collision_next(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t next)
{
struct ocf_metadata_list_info *info;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
info = ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
if (info)
info->next_col = next;
else
ocf_metadata_error(cache);
}
void ocf_metadata_set_collision_prev(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t prev)
{
struct ocf_metadata_list_info *info;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
info = ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
if (info)
info->prev_col = prev;
else
ocf_metadata_error(cache);
}
void ocf_metadata_get_collision_info(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t *next,
ocf_cache_line_t *prev)
{
const struct ocf_metadata_list_info *info;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
ENV_BUG_ON(NULL == next && NULL == prev);
info = ocf_metadata_raw_rd_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
if (info) {
if (next)
*next = info->next_col;
if (prev)
*prev = info->prev_col;
} else {
ocf_metadata_error(cache);
if (next)
*next = cache->device->collision_table_entries;
if (prev)
*prev = cache->device->collision_table_entries;
}
}
/* /*
* *
*/ */
@ -86,3 +303,29 @@ void ocf_metadata_remove_from_collision(struct ocf_cache *cache,
ocf_metadata_set_core_info(cache, line, ocf_metadata_set_core_info(cache, line,
OCF_CORE_MAX, ULLONG_MAX); OCF_CORE_MAX, ULLONG_MAX);
} }
void ocf_metadata_start_collision_shared_access(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];
uint32_t page = ocf_metadata_raw_page(raw, line);
ocf_collision_start_shared_access(&cache->metadata.lock, page);
}
void ocf_metadata_end_collision_shared_access(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];
uint32_t page = ocf_metadata_raw_page(raw, line);
ocf_collision_end_shared_access(&cache->metadata.lock, page);
}

View File

@ -38,47 +38,27 @@ struct ocf_metadata_map {
/*!< Entry status structure e.g. valid, dirty...*/ /*!< Entry status structure e.g. valid, dirty...*/
} __attribute__((packed)); } __attribute__((packed));
static inline ocf_cache_line_t ocf_metadata_map_lg2phy( ocf_cache_line_t ocf_metadata_map_lg2phy(
struct ocf_cache *cache, ocf_cache_line_t coll_idx) struct ocf_cache *cache, ocf_cache_line_t coll_idx);
{
return cache->metadata.iface.layout_iface->lg2phy(cache,
coll_idx);
}
static inline ocf_cache_line_t ocf_metadata_map_phy2lg( ocf_cache_line_t ocf_metadata_map_phy2lg(
struct ocf_cache *cache, ocf_cache_line_t cache_line) struct ocf_cache *cache, ocf_cache_line_t cache_line);
{
return cache->metadata.iface.layout_iface->phy2lg(cache,
cache_line);
}
static inline void ocf_metadata_set_collision_info( void ocf_metadata_set_collision_info(
struct ocf_cache *cache, ocf_cache_line_t line, struct ocf_cache *cache, ocf_cache_line_t line,
ocf_cache_line_t next, ocf_cache_line_t prev) ocf_cache_line_t next, ocf_cache_line_t prev);
{
cache->metadata.iface.set_collision_info(cache, line, next, prev);
}
static inline void ocf_metadata_set_collision_next( void ocf_metadata_set_collision_next(
struct ocf_cache *cache, ocf_cache_line_t line, struct ocf_cache *cache, ocf_cache_line_t line,
ocf_cache_line_t next) ocf_cache_line_t next);
{
cache->metadata.iface.set_collision_next(cache, line, next);
}
static inline void ocf_metadata_set_collision_prev( void ocf_metadata_set_collision_prev(
struct ocf_cache *cache, ocf_cache_line_t line, struct ocf_cache *cache, ocf_cache_line_t line,
ocf_cache_line_t prev) ocf_cache_line_t prev);
{
cache->metadata.iface.set_collision_prev(cache, line, prev);
}
static inline void ocf_metadata_get_collision_info( void ocf_metadata_get_collision_info(
struct ocf_cache *cache, ocf_cache_line_t line, struct ocf_cache *cache, ocf_cache_line_t line,
ocf_cache_line_t *next, ocf_cache_line_t *prev) ocf_cache_line_t *next, ocf_cache_line_t *prev);
{
cache->metadata.iface.get_collision_info(cache, line, next, prev);
}
static inline ocf_cache_line_t ocf_metadata_get_collision_next( static inline ocf_cache_line_t ocf_metadata_get_collision_next(
struct ocf_cache *cache, ocf_cache_line_t line) struct ocf_cache *cache, ocf_cache_line_t line)
@ -105,16 +85,10 @@ void ocf_metadata_add_to_collision(struct ocf_cache *cache,
void ocf_metadata_remove_from_collision(struct ocf_cache *cache, void ocf_metadata_remove_from_collision(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_part_id_t part_id); ocf_cache_line_t line, ocf_part_id_t part_id);
static inline void ocf_metadata_start_collision_shared_access( void ocf_metadata_start_collision_shared_access(
struct ocf_cache *cache, ocf_cache_line_t line) struct ocf_cache *cache, ocf_cache_line_t line);
{
cache->metadata.iface.start_collision_shared_access(cache, line);
}
static inline void ocf_metadata_end_collision_shared_access( void ocf_metadata_end_collision_shared_access(
struct ocf_cache *cache, ocf_cache_line_t line) struct ocf_cache *cache, ocf_cache_line_t line);
{
cache->metadata.iface.end_collision_shared_access(cache, line);
}
#endif /* METADATA_COLLISION_H_ */ #endif /* METADATA_COLLISION_H_ */

View File

@ -0,0 +1,88 @@
/*
* Copyright(c) 2020 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include "ocf/ocf.h"
#include "../ocf_priv.h"
#include "metadata.h"
#include "metadata_core.h"
#include "metadata_internal.h"
#include "metadata_raw.h"
void ocf_metadata_get_core_info(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_core_id_t *core_id,
uint64_t *core_sector)
{
const struct ocf_metadata_map *collision;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
collision = ocf_metadata_raw_rd_access(cache,
&(ctrl->raw_desc[metadata_segment_collision]), line);
if (collision) {
if (core_id)
*core_id = collision->core_id;
if (core_sector)
*core_sector = collision->core_line;
} else {
ocf_metadata_error(cache);
if (core_id)
*core_id = OCF_CORE_MAX;
if (core_sector)
*core_sector = ULLONG_MAX;
}
}
void ocf_metadata_set_core_info(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_core_id_t core_id,
uint64_t core_sector)
{
struct ocf_metadata_map *collision;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
collision = ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_collision]), line);
if (collision) {
collision->core_id = core_id;
collision->core_line = core_sector;
} else {
ocf_metadata_error(cache);
}
}
ocf_core_id_t ocf_metadata_get_core_id(struct ocf_cache *cache,
ocf_cache_line_t line)
{
const struct ocf_metadata_map *collision;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
collision = ocf_metadata_raw_rd_access(cache,
&(ctrl->raw_desc[metadata_segment_collision]), line);
if (collision)
return collision->core_id;
ocf_metadata_error(cache);
return OCF_CORE_MAX;
}
struct ocf_metadata_uuid *ocf_metadata_get_core_uuid(
struct ocf_cache *cache, ocf_core_id_t core_id)
{
struct ocf_metadata_uuid *muuid;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
muuid = ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_core_uuid]), core_id);
if (!muuid)
ocf_metadata_error(cache);
return muuid;
}

View File

@ -6,40 +6,24 @@
#ifndef __METADATA_CORE_H__ #ifndef __METADATA_CORE_H__
#define __METADATA_CORE_H__ #define __METADATA_CORE_H__
static inline void ocf_metadata_set_core_info(struct ocf_cache *cache, #include <ocf/ocf_types.h>
ocf_cache_line_t line, ocf_core_id_t core_id,
uint64_t core_sector)
{
cache->metadata.iface.set_core_info(cache, line, core_id,
core_sector);
}
static inline void ocf_metadata_get_core_info(struct ocf_cache *cache, void ocf_metadata_get_core_info(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_core_id_t *core_id, ocf_cache_line_t line, ocf_core_id_t *core_id,
uint64_t *core_sector) uint64_t *core_sector);
{
cache->metadata.iface.get_core_info(cache, line, core_id,
core_sector);
}
static inline void ocf_metadata_get_core_and_part_id( void ocf_metadata_set_core_info(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_core_id_t core_id,
uint64_t core_sector);
ocf_core_id_t ocf_metadata_get_core_id(
struct ocf_cache *cache, ocf_cache_line_t line);
struct ocf_metadata_uuid *ocf_metadata_get_core_uuid(
struct ocf_cache *cache, ocf_core_id_t core_id);
void ocf_metadata_get_core_and_part_id(
struct ocf_cache *cache, ocf_cache_line_t line, struct ocf_cache *cache, ocf_cache_line_t line,
ocf_core_id_t *core_id, ocf_part_id_t *part_id) ocf_core_id_t *core_id, ocf_part_id_t *part_id);
{
cache->metadata.iface.get_core_and_part_id(cache, line, core_id,
part_id);
}
static inline ocf_core_id_t ocf_metadata_get_core_id(
struct ocf_cache *cache, ocf_cache_line_t line)
{
return cache->metadata.iface.get_core_id(cache, line);
}
static inline struct ocf_metadata_uuid *ocf_metadata_get_core_uuid(
struct ocf_cache *cache, ocf_core_id_t core_id)
{
return cache->metadata.iface.get_core_uuid(cache, core_id);
}
#endif /* METADATA_CORE_H_ */ #endif /* METADATA_CORE_H_ */

View File

@ -0,0 +1,25 @@
/*
* copyright(c )2020 intel corporation
* spdx-license-identifier: bsd-3-clause-clear
*/
#include "ocf/ocf.h"
#include "metadata.h"
#include "metadata_eviction_policy.h"
#include "metadata_internal.h"
/*
* Eviction policy - Get
*/
union eviction_policy_meta *
ocf_metadata_get_eviction_policy(struct ocf_cache *cache,
ocf_cache_line_t line)
{
struct ocf_metadata_ctrl *ctrl
= (struct ocf_metadata_ctrl *) cache->metadata.priv;
return ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_eviction]), line);
}

View File

@ -6,11 +6,8 @@
#ifndef __METADATA_EVICTION_H__ #ifndef __METADATA_EVICTION_H__
#define __METADATA_EVICTION_H__ #define __METADATA_EVICTION_H__
static inline union eviction_policy_meta * union eviction_policy_meta *
ocf_metadata_get_eviction_policy( ocf_metadata_get_eviction_policy(
struct ocf_cache *cache, ocf_cache_line_t line) struct ocf_cache *cache, ocf_cache_line_t line);
{
return cache->metadata.iface.get_eviction_policy(cache, line);
}
#endif /* METADATA_EVICTION_H_ */ #endif /* METADATA_EVICTION_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
/*
* Copyright(c) 2020 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef __METADATA_INTERNAL_H__
#define __METADATA_INTERNAL_H__
#include <ocf/ocf_def.h>
#include "../ocf_cache_priv.h"
#include "metadata_segment.h"
#include "metadata_segment_id.h"
#include "metadata_raw.h"
#define METADATA_MEM_POOL(ctrl, section) ctrl->raw_desc[section].mem_pool
/*
* Metadata control structure
*/
struct ocf_metadata_ctrl {
ocf_cache_line_t cachelines;
ocf_cache_line_t start_page;
ocf_cache_line_t count_pages;
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 {
ocf_metadata_end_t cmpl;
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];
};
extern const char * const ocf_metadata_segment_names[];
#endif

View File

@ -5,8 +5,89 @@
#include "ocf/ocf.h" #include "ocf/ocf.h"
#include "metadata.h" #include "metadata.h"
#include "metadata_internal.h"
#include "../utils/utils_part.h" #include "../utils/utils_part.h"
void ocf_metadata_get_partition_info(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_part_id_t *part_id,
ocf_cache_line_t *next_line, ocf_cache_line_t *prev_line)
{
const struct ocf_metadata_list_info *info;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
info = ocf_metadata_raw_rd_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
if (info) {
if (part_id)
*part_id = info->partition_id;
if (next_line)
*next_line = info->partition_next;
if (prev_line)
*prev_line = info->partition_prev;
} else {
ocf_metadata_error(cache);
if (part_id)
*part_id = PARTITION_DEFAULT;
if (next_line)
*next_line = cache->device->collision_table_entries;
if (prev_line)
*prev_line = cache->device->collision_table_entries;
}
}
void ocf_metadata_set_partition_next(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t next_line)
{
struct ocf_metadata_list_info *info;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
info = ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
if (info)
info->partition_next = next_line;
else
ocf_metadata_error(cache);
}
void ocf_metadata_set_partition_prev(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t prev_line)
{
struct ocf_metadata_list_info *info;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
info = ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
if (info)
info->partition_prev = prev_line;
else
ocf_metadata_error(cache);
}
void ocf_metadata_set_partition_info(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_part_id_t part_id,
ocf_cache_line_t next_line, ocf_cache_line_t prev_line)
{
struct ocf_metadata_list_info *info;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;
info = ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
if (info) {
info->partition_id = part_id;
info->partition_next = next_line;
info->partition_prev = prev_line;
} else {
ocf_metadata_error(cache);
}
}
/* Sets the given collision_index as the new _head_ of the Partition list. */ /* Sets the given collision_index as the new _head_ of the Partition list. */
static void update_partition_head(struct ocf_cache *cache, static void update_partition_head(struct ocf_cache *cache,
ocf_part_id_t part_id, ocf_cache_line_t line) ocf_part_id_t part_id, ocf_cache_line_t line)

View File

@ -13,14 +13,10 @@
#define PARTITION_INVALID ((ocf_part_id_t)-1) #define PARTITION_INVALID ((ocf_part_id_t)-1)
#define PARTITION_SIZE_MAX ((ocf_cache_line_t)-1) #define PARTITION_SIZE_MAX ((ocf_cache_line_t)-1)
static inline void ocf_metadata_get_partition_info( void ocf_metadata_get_partition_info(
struct ocf_cache *cache, ocf_cache_line_t line, struct ocf_cache *cache, ocf_cache_line_t line,
ocf_part_id_t *part_id, ocf_cache_line_t *next_line, ocf_part_id_t *part_id, ocf_cache_line_t *next_line,
ocf_cache_line_t *prev_line) ocf_cache_line_t *prev_line);
{
cache->metadata.iface.get_partition_info(cache, line, part_id,
next_line, prev_line);
}
static inline ocf_part_id_t ocf_metadata_get_partition_id( static inline ocf_part_id_t ocf_metadata_get_partition_id(
struct ocf_cache *cache, ocf_cache_line_t line) struct ocf_cache *cache, ocf_cache_line_t line)
@ -52,28 +48,18 @@ static inline ocf_cache_line_t ocf_metadata_get_partition_prev(
return prev; return prev;
} }
static inline void ocf_metadata_set_partition_next( void ocf_metadata_set_partition_next(
struct ocf_cache *cache, ocf_cache_line_t line, struct ocf_cache *cache, ocf_cache_line_t line,
ocf_cache_line_t next_line) ocf_cache_line_t next_line);
{
cache->metadata.iface.set_partition_next(cache, line, next_line);
}
static inline void ocf_metadata_set_partition_prev( void ocf_metadata_set_partition_prev(
struct ocf_cache *cache, ocf_cache_line_t line, struct ocf_cache *cache, ocf_cache_line_t line,
ocf_cache_line_t prev_line) ocf_cache_line_t prev_line);
{
cache->metadata.iface.set_partition_prev(cache, line, prev_line);
}
static inline void ocf_metadata_set_partition_info( void ocf_metadata_set_partition_info(
struct ocf_cache *cache, ocf_cache_line_t line, struct ocf_cache *cache, ocf_cache_line_t line,
ocf_part_id_t part_id, ocf_cache_line_t next_line, ocf_part_id_t part_id, ocf_cache_line_t next_line,
ocf_cache_line_t prev_line) ocf_cache_line_t prev_line);
{
cache->metadata.iface.set_partition_info(cache, line, part_id,
next_line, prev_line);
}
void ocf_metadata_add_to_partition(struct ocf_cache *cache, void ocf_metadata_add_to_partition(struct ocf_cache *cache,
ocf_part_id_t part_id, ocf_cache_line_t line); ocf_part_id_t part_id, ocf_cache_line_t line);

View File

@ -4,7 +4,7 @@
*/ */
#include "metadata.h" #include "metadata.h"
#include "metadata_hash.h" #include "metadata_segment_id.h"
#include "metadata_raw.h" #include "metadata_raw.h"
#include "metadata_io.h" #include "metadata_io.h"
#include "metadata_raw_atomic.h" #include "metadata_raw_atomic.h"
@ -164,17 +164,6 @@ uint32_t _raw_ram_page(struct ocf_metadata_raw *raw, uint32_t entry)
return _RAW_RAM_PAGE(raw, entry); return _RAW_RAM_PAGE(raw, entry);
} }
/*
* RAM Implementation - Get entry
*/
static int _raw_ram_get(ocf_cache_t cache, struct ocf_metadata_raw *raw,
uint32_t entry, void *data)
{
ENV_BUG_ON(!_raw_is_valid(raw, entry));
return _RAW_RAM_GET(raw, entry, data);
}
/* /*
* RAM Implementation - Read only entry access * RAM Implementation - Read only entry access
*/ */
@ -186,17 +175,6 @@ static void *_raw_ram_access(ocf_cache_t cache,
return _RAW_RAM_ADDR(raw, entry); return _RAW_RAM_ADDR(raw, entry);
} }
/*
* RAM Implementation - Set Entry
*/
static int _raw_ram_set(ocf_cache_t cache, struct ocf_metadata_raw *raw,
uint32_t entry, void *data)
{
ENV_BUG_ON(!_raw_is_valid(raw, entry));
return _RAW_RAM_SET(raw, entry, data);
}
struct _raw_ram_load_all_context { struct _raw_ram_load_all_context {
struct ocf_metadata_raw *raw; struct ocf_metadata_raw *raw;
ocf_metadata_end_t cmpl; ocf_metadata_end_t cmpl;
@ -568,8 +546,6 @@ static const struct raw_iface IRAW[metadata_raw_type_max] = {
.size_on_ssd = _raw_ram_size_on_ssd, .size_on_ssd = _raw_ram_size_on_ssd,
.checksum = _raw_ram_checksum, .checksum = _raw_ram_checksum,
.page = _raw_ram_page, .page = _raw_ram_page,
.get = _raw_ram_get,
.set = _raw_ram_set,
.access = _raw_ram_access, .access = _raw_ram_access,
.load_all = _raw_ram_load_all, .load_all = _raw_ram_load_all,
.flush_all = _raw_ram_flush_all, .flush_all = _raw_ram_flush_all,
@ -583,8 +559,6 @@ static const struct raw_iface IRAW[metadata_raw_type_max] = {
.size_on_ssd = raw_dynamic_size_on_ssd, .size_on_ssd = raw_dynamic_size_on_ssd,
.checksum = raw_dynamic_checksum, .checksum = raw_dynamic_checksum,
.page = raw_dynamic_page, .page = raw_dynamic_page,
.get = raw_dynamic_get,
.set = raw_dynamic_set,
.access = raw_dynamic_access, .access = raw_dynamic_access,
.load_all = raw_dynamic_load_all, .load_all = raw_dynamic_load_all,
.flush_all = raw_dynamic_flush_all, .flush_all = raw_dynamic_flush_all,
@ -598,8 +572,6 @@ static const struct raw_iface IRAW[metadata_raw_type_max] = {
.size_on_ssd = raw_volatile_size_on_ssd, .size_on_ssd = raw_volatile_size_on_ssd,
.checksum = raw_volatile_checksum, .checksum = raw_volatile_checksum,
.page = _raw_ram_page, .page = _raw_ram_page,
.get = _raw_ram_get,
.set = _raw_ram_set,
.access = _raw_ram_access, .access = _raw_ram_access,
.load_all = raw_volatile_load_all, .load_all = raw_volatile_load_all,
.flush_all = raw_volatile_flush_all, .flush_all = raw_volatile_flush_all,
@ -613,8 +585,6 @@ static const struct raw_iface IRAW[metadata_raw_type_max] = {
.size_on_ssd = _raw_ram_size_on_ssd, .size_on_ssd = _raw_ram_size_on_ssd,
.checksum = _raw_ram_checksum, .checksum = _raw_ram_checksum,
.page = _raw_ram_page, .page = _raw_ram_page,
.get = _raw_ram_get,
.set = _raw_ram_set,
.access = _raw_ram_access, .access = _raw_ram_access,
.load_all = _raw_ram_load_all, .load_all = _raw_ram_load_all,
.flush_all = _raw_ram_flush_all, .flush_all = _raw_ram_flush_all,

View File

@ -6,6 +6,8 @@
#ifndef __METADATA_RAW_H__ #ifndef __METADATA_RAW_H__
#define __METADATA_RAW_H__ #define __METADATA_RAW_H__
#include "metadata_segment_id.h"
/** /**
* @file metadata_raw.h * @file metadata_raw.h
* @brief Metadata RAW container implementation * @brief Metadata RAW container implementation
@ -57,7 +59,7 @@ struct ocf_metadata_raw {
/** /**
* @name Metadata and RAW types * @name Metadata and RAW types
*/ */
enum ocf_metadata_segment metadata_segment; /*!< Metadata segment */ enum ocf_metadata_segment_id metadata_segment; /*!< Metadata segment */
enum ocf_metadata_raw_type raw_type; /*!< RAW implementation type */ enum ocf_metadata_raw_type raw_type; /*!< RAW implementation type */
/** /**
@ -117,12 +119,6 @@ struct raw_iface {
uint32_t (*page)(struct ocf_metadata_raw *raw, uint32_t entry); uint32_t (*page)(struct ocf_metadata_raw *raw, uint32_t entry);
int (*get)(ocf_cache_t cache, struct ocf_metadata_raw *raw,
uint32_t entry, void *data);
int (*set)(ocf_cache_t cache, struct ocf_metadata_raw *raw,
uint32_t entry, void *data);
void* (*access)(ocf_cache_t cache, struct ocf_metadata_raw *raw, void* (*access)(ocf_cache_t cache, struct ocf_metadata_raw *raw,
uint32_t entry); uint32_t entry);
@ -214,21 +210,6 @@ static inline uint32_t ocf_metadata_raw_page(struct ocf_metadata_raw* raw,
return raw->iface->page(raw, entry); return raw->iface->page(raw, entry);
} }
/**
* @brief Get specified element of metadata
*
* @param cache - Cache instance
* @param raw - RAW descriptor
* @param entry - Entry to be get
* @param data - Data where metadata entry will be copied into
* @return 0 - Operation success, otherwise error
*/
static inline int ocf_metadata_raw_get(ocf_cache_t cache,
struct ocf_metadata_raw *raw, uint32_t entry, void *data)
{
return raw->iface->get(cache, raw, entry, data);
}
/** /**
* @brief Access specified element of metadata directly * @brief Access specified element of metadata directly
* *
@ -259,21 +240,6 @@ static inline const void *ocf_metadata_raw_rd_access( ocf_cache_t cache,
return raw->iface->access(cache, raw, entry); return raw->iface->access(cache, raw, entry);
} }
/**
* @brief Set specified element of metadata
*
* @param cache - Cache instance
* @param raw - RAW descriptor
* @param entry - Entry to be set
* @param data - Data taht will be copied into metadata entry
* @return 0 - Operation success, otherwise error
*/
static inline int ocf_metadata_raw_set(ocf_cache_t cache,
struct ocf_metadata_raw *raw, uint32_t entry, void *data)
{
return raw->iface->set(cache, raw, entry, data);
}
/** /**
* @brief Load all entries from SSD cache (cahce cache) * @brief Load all entries from SSD cache (cahce cache)
* *
@ -342,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); 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_ */ #endif /* METADATA_RAW_H_ */

View File

@ -5,7 +5,7 @@
#include "metadata.h" #include "metadata.h"
#include "metadata_io.h" #include "metadata_io.h"
#include "metadata_hash.h" #include "metadata_segment_id.h"
#include "metadata_raw.h" #include "metadata_raw.h"
#include "metadata_raw_atomic.h" #include "metadata_raw_atomic.h"
#include "../utils/utils_io.h" #include "../utils/utils_io.h"

View File

@ -4,7 +4,7 @@
*/ */
#include "metadata.h" #include "metadata.h"
#include "metadata_hash.h" #include "metadata_segment_id.h"
#include "metadata_raw.h" #include "metadata_raw.h"
#include "metadata_raw_dynamic.h" #include "metadata_raw_dynamic.h"
#include "metadata_io.h" #include "metadata_io.h"
@ -234,39 +234,6 @@ uint32_t raw_dynamic_page(struct ocf_metadata_raw *raw, uint32_t entry)
return _RAW_DYNAMIC_PAGE(raw, entry); return _RAW_DYNAMIC_PAGE(raw, entry);
} }
/*
* RAM DYNAMIC Implementation - Get
*/
int raw_dynamic_get(ocf_cache_t cache, struct ocf_metadata_raw *raw,
uint32_t entry, void *data)
{
void *item = _raw_dynamic_get_item(cache, raw, entry);
if (!item) {
ENV_BUG_ON(env_memset(data, raw->entry_size, 0));
ocf_metadata_error(cache);
return -1;
}
return env_memcpy(data, raw->entry_size, item, raw->entry_size);
}
/*
* RAM DYNAMIC Implementation - Set
*/
int raw_dynamic_set(ocf_cache_t cache, struct ocf_metadata_raw *raw,
uint32_t entry, void *data)
{
void *item = _raw_dynamic_get_item(cache, raw, entry);
if (!item) {
ocf_metadata_error(cache);
return -1;
}
return env_memcpy(item, raw->entry_size, data, raw->entry_size);
}
/* /*
* RAM DYNAMIC Implementation - access * RAM DYNAMIC Implementation - access
*/ */

View File

@ -47,18 +47,6 @@ uint32_t raw_dynamic_checksum(ocf_cache_t cache,
*/ */
uint32_t raw_dynamic_page(struct ocf_metadata_raw *raw, uint32_t entry); uint32_t raw_dynamic_page(struct ocf_metadata_raw *raw, uint32_t entry);
/*
* RAW DYNAMIC - Get specified entry
*/
int raw_dynamic_get(ocf_cache_t cache, struct ocf_metadata_raw *raw,
uint32_t entry, void *data);
/*
* RAW DYNAMIC - Set specified entry
*/
int raw_dynamic_set(ocf_cache_t cache, struct ocf_metadata_raw *raw,
uint32_t entry, void *data);
/* /*
* RAW DYNAMIC - Write access for specified entry * RAW DYNAMIC - Write access for specified entry
*/ */

View File

@ -4,7 +4,7 @@
*/ */
#include "metadata.h" #include "metadata.h"
#include "metadata_hash.h" #include "metadata_segment_id.h"
#include "metadata_raw.h" #include "metadata_raw.h"
#include "metadata_io.h" #include "metadata_io.h"
#include "metadata_raw_volatile.h" #include "metadata_raw_volatile.h"

View File

@ -0,0 +1,159 @@
/*
* Copyright(c) 2020 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#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)
{
struct ocf_metadata_context *context = priv;
OCF_PL_NEXT_ON_SUCCESS_RET(context->pipeline, error);
}
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_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;
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, segment->raw);
superblock_crc = ocf_metadata_superblock_get_checksum(segment->superblock,
segment_id);
if (crc != superblock_crc) {
/* Checksum does not match */
if (!clean_shutdown) {
ocf_cache_log(cache, log_warn,
"Loading %s WARNING, invalid checksum",
ocf_metadata_segment_names[segment_id]);
} else {
ocf_cache_log(cache, log_err,
"Loading %s ERROR, invalid checksum",
ocf_metadata_segment_names[segment_id]);
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL);
}
}
ocf_pipeline_next(pipeline);
}
void ocf_metadata_check_crc(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
ocf_metadata_check_crc_skip(pipeline, priv, arg, false);
}
void ocf_metadata_check_crc_if_clean(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
ocf_metadata_check_crc_skip(pipeline, priv, arg, true);
}
void ocf_metadata_calculate_crc(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_metadata_context *context = priv;
int segment_id = ocf_pipeline_arg_get_int(arg);
struct ocf_metadata_segment *segment = context->ctrl->segment[segment_id];
ocf_metadata_superblock_set_checksum(segment->superblock, segment_id,
ocf_metadata_raw_checksum(context->cache, segment->raw));
ocf_pipeline_next(pipeline);
}
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;
ocf_cache_t cache = context->cache;
ocf_metadata_raw_flush_all(cache, &ctrl->raw_desc[segment],
ocf_metadata_generic_complete, context);
}
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;
ocf_cache_t cache = context->cache;
ocf_metadata_raw_load_all(cache, &ctrl->raw_desc[segment],
ocf_metadata_generic_complete, context);
}

View File

@ -0,0 +1,44 @@
/*
* Copyright(c) 2020 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef __METADATA_SEGMENT_OPS_H__
#define __METADATA_SEGMENT_OPS_H__
#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);
void ocf_metadata_check_crc(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg);
void ocf_metadata_calculate_crc(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg);
void ocf_metadata_flush_segment(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg);
void ocf_metadata_load_segment(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg);
#endif

View File

@ -15,7 +15,7 @@
/** /**
* @brief Metada hash elements type * @brief Metada hash elements type
*/ */
enum ocf_metadata_segment { enum ocf_metadata_segment_id {
metadata_segment_sb_config = 0, /*!< Super block conf */ metadata_segment_sb_config = 0, /*!< Super block conf */
metadata_segment_sb_runtime, /*!< Super block runtime */ metadata_segment_sb_runtime, /*!< Super block runtime */
metadata_segment_reserved, /*!< Reserved space on disk */ metadata_segment_reserved, /*!< Reserved space on disk */
@ -41,11 +41,4 @@ enum ocf_metadata_segment {
metadata_segment_max, /*!< MAX */ metadata_segment_max, /*!< MAX */
}; };
/**
* @brief Get metadata interface implementation
*
* @return metadata interface
*/
const struct ocf_metadata_iface *metadata_hash_get_iface(void);
#endif /* METADATA_HASH_H_ */ #endif /* METADATA_HASH_H_ */

View File

@ -12,15 +12,29 @@
* Dirty * Dirty
******************************************************************************/ ******************************************************************************/
bool ocf_metadata_test_dirty(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
bool ocf_metadata_test_out_dirty(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool ocf_metadata_clear_dirty(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool ocf_metadata_set_dirty(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool ocf_metadata_test_and_set_dirty(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
bool ocf_metadata_test_and_clear_dirty(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
bool ocf_metadata_test_valid(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
bool ocf_metadata_test_out_valid(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool ocf_metadata_clear_valid(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool ocf_metadata_set_valid(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool ocf_metadata_test_and_set_valid(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
bool ocf_metadata_test_and_clear_valid(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
static inline void metadata_init_status_bits(struct ocf_cache *cache, static inline void metadata_init_status_bits(struct ocf_cache *cache,
ocf_cache_line_t line) ocf_cache_line_t line)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.clear_dirty(cache, line, ocf_metadata_clear_dirty(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end); cache->metadata.settings.sector_end);
cache->metadata.iface.clear_valid(cache, line, ocf_metadata_clear_valid(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end); cache->metadata.settings.sector_end);
@ -33,7 +47,7 @@ static inline bool metadata_test_dirty_all(struct ocf_cache *cache,
bool test; bool test;
OCF_METADATA_BITS_LOCK_RD(); OCF_METADATA_BITS_LOCK_RD();
test = cache->metadata.iface.test_dirty(cache, line, test = ocf_metadata_test_dirty(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end, true); cache->metadata.settings.sector_end, true);
OCF_METADATA_BITS_UNLOCK_RD(); OCF_METADATA_BITS_UNLOCK_RD();
@ -47,7 +61,7 @@ static inline bool metadata_test_dirty(struct ocf_cache *cache,
bool test; bool test;
OCF_METADATA_BITS_LOCK_RD(); OCF_METADATA_BITS_LOCK_RD();
test = cache->metadata.iface.test_dirty(cache, line, test = ocf_metadata_test_dirty(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end, false); cache->metadata.settings.sector_end, false);
OCF_METADATA_BITS_UNLOCK_RD(); OCF_METADATA_BITS_UNLOCK_RD();
@ -59,7 +73,7 @@ static inline void metadata_set_dirty(struct ocf_cache *cache,
ocf_cache_line_t line) ocf_cache_line_t line)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.set_dirty(cache, line, ocf_metadata_set_dirty(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end); cache->metadata.settings.sector_end);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -69,7 +83,7 @@ static inline void metadata_clear_dirty(struct ocf_cache *cache,
ocf_cache_line_t line) ocf_cache_line_t line)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.clear_dirty(cache, line, ocf_metadata_clear_dirty(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end); cache->metadata.settings.sector_end);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -81,7 +95,7 @@ static inline bool metadata_test_and_clear_dirty(
bool test; bool test;
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
test = cache->metadata.iface.test_and_clear_dirty(cache, line, test = ocf_metadata_test_and_clear_dirty(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end, false); cache->metadata.settings.sector_end, false);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -95,7 +109,7 @@ static inline bool metadata_test_and_set_dirty(struct ocf_cache *cache,
bool test; bool test;
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
test = cache->metadata.iface.test_and_set_dirty(cache, line, test = ocf_metadata_test_and_set_dirty(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end, false); cache->metadata.settings.sector_end, false);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -113,7 +127,7 @@ static inline bool metadata_test_dirty_sec(struct ocf_cache *cache,
bool test; bool test;
OCF_METADATA_BITS_LOCK_RD(); OCF_METADATA_BITS_LOCK_RD();
test = cache->metadata.iface.test_dirty(cache, line, test = ocf_metadata_test_dirty(cache, line,
start, stop, false); start, stop, false);
OCF_METADATA_BITS_UNLOCK_RD(); OCF_METADATA_BITS_UNLOCK_RD();
@ -126,7 +140,7 @@ static inline bool metadata_test_dirty_all_sec(struct ocf_cache *cache,
bool test; bool test;
OCF_METADATA_BITS_LOCK_RD(); OCF_METADATA_BITS_LOCK_RD();
test = cache->metadata.iface.test_dirty(cache, line, test = ocf_metadata_test_dirty(cache, line,
start, stop, true); start, stop, true);
OCF_METADATA_BITS_UNLOCK_RD(); OCF_METADATA_BITS_UNLOCK_RD();
@ -145,7 +159,7 @@ static inline bool metadata_test_dirty_out_sec(struct ocf_cache *cache,
bool test; bool test;
OCF_METADATA_BITS_LOCK_RD(); OCF_METADATA_BITS_LOCK_RD();
test = cache->metadata.iface.test_out_dirty(cache, line, start, stop); test = ocf_metadata_test_out_dirty(cache, line, start, stop);
OCF_METADATA_BITS_UNLOCK_RD(); OCF_METADATA_BITS_UNLOCK_RD();
return test; return test;
@ -155,7 +169,7 @@ static inline void metadata_set_dirty_sec(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop) ocf_cache_line_t line, uint8_t start, uint8_t stop)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.set_dirty(cache, line, start, stop); ocf_metadata_set_dirty(cache, line, start, stop);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
} }
@ -163,7 +177,7 @@ static inline void metadata_clear_dirty_sec(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop) ocf_cache_line_t line, uint8_t start, uint8_t stop)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.clear_dirty(cache, line, start, stop); ocf_metadata_clear_dirty(cache, line, start, stop);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
} }
@ -171,7 +185,7 @@ static inline void metadata_set_dirty_sec_one(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t pos) ocf_cache_line_t line, uint8_t pos)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.set_dirty(cache, line, pos, pos); ocf_metadata_set_dirty(cache, line, pos, pos);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
} }
@ -179,7 +193,7 @@ static inline void metadata_clear_dirty_sec_one(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t pos) ocf_cache_line_t line, uint8_t pos)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.clear_dirty(cache, line, pos, pos); ocf_metadata_clear_dirty(cache, line, pos, pos);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
} }
@ -190,7 +204,7 @@ static inline bool metadata_test_and_clear_dirty_sec(
bool test = false; bool test = false;
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
test = cache->metadata.iface.test_and_clear_dirty(cache, line, test = ocf_metadata_test_and_clear_dirty(cache, line,
start, stop, false); start, stop, false);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -211,9 +225,9 @@ static inline bool metadata_clear_dirty_sec_changed(
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
sec_changed = cache->metadata.iface.test_dirty(cache, line, sec_changed = ocf_metadata_test_dirty(cache, line,
start, stop, false); start, stop, false);
*line_is_clean = !cache->metadata.iface.clear_dirty(cache, line, *line_is_clean = !ocf_metadata_clear_dirty(cache, line,
start, stop); start, stop);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -234,9 +248,9 @@ static inline bool metadata_set_dirty_sec_changed(
bool sec_changed; bool sec_changed;
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
sec_changed = !cache->metadata.iface.test_dirty(cache, line, sec_changed = !ocf_metadata_test_dirty(cache, line,
start, stop, true); start, stop, true);
*line_was_dirty = cache->metadata.iface.set_dirty(cache, line, start, *line_was_dirty = ocf_metadata_set_dirty(cache, line, start,
stop); stop);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -253,7 +267,7 @@ static inline bool metadata_test_valid_any(struct ocf_cache *cache,
bool test; bool test;
OCF_METADATA_BITS_LOCK_RD(); OCF_METADATA_BITS_LOCK_RD();
test = cache->metadata.iface.test_valid(cache, line, test = ocf_metadata_test_valid(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end, false); cache->metadata.settings.sector_end, false);
OCF_METADATA_BITS_UNLOCK_RD(); OCF_METADATA_BITS_UNLOCK_RD();
@ -267,7 +281,7 @@ static inline bool metadata_test_valid(struct ocf_cache *cache,
bool test; bool test;
OCF_METADATA_BITS_LOCK_RD(); OCF_METADATA_BITS_LOCK_RD();
test = cache->metadata.iface.test_valid(cache, line, test = ocf_metadata_test_valid(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end, true); cache->metadata.settings.sector_end, true);
OCF_METADATA_BITS_UNLOCK_RD(); OCF_METADATA_BITS_UNLOCK_RD();
@ -279,7 +293,7 @@ static inline void metadata_set_valid(struct ocf_cache *cache,
ocf_cache_line_t line) ocf_cache_line_t line)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.set_valid(cache, line, ocf_metadata_set_valid(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end); cache->metadata.settings.sector_end);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -289,7 +303,7 @@ static inline void metadata_clear_valid(struct ocf_cache *cache,
ocf_cache_line_t line) ocf_cache_line_t line)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.clear_valid(cache, line, ocf_metadata_clear_valid(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end); cache->metadata.settings.sector_end);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -301,7 +315,7 @@ static inline bool metadata_test_and_clear_valid(
bool test = false; bool test = false;
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
test = cache->metadata.iface.test_and_clear_valid(cache, line, test = ocf_metadata_test_and_clear_valid(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end, true); cache->metadata.settings.sector_end, true);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -315,7 +329,7 @@ static inline bool metadata_test_and_set_valid(struct ocf_cache *cache,
bool test = false; bool test = false;
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
test = cache->metadata.iface.test_and_set_valid(cache, line, test = ocf_metadata_test_and_set_valid(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end, true); cache->metadata.settings.sector_end, true);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -333,7 +347,7 @@ static inline bool metadata_test_valid_sec(struct ocf_cache *cache,
bool test; bool test;
OCF_METADATA_BITS_LOCK_RD(); OCF_METADATA_BITS_LOCK_RD();
test = cache->metadata.iface.test_valid(cache, line, test = ocf_metadata_test_valid(cache, line,
start, stop, true); start, stop, true);
OCF_METADATA_BITS_UNLOCK_RD(); OCF_METADATA_BITS_UNLOCK_RD();
@ -347,7 +361,7 @@ static inline bool metadata_test_valid_any_out_sec(
bool test = false; bool test = false;
OCF_METADATA_BITS_LOCK_RD(); OCF_METADATA_BITS_LOCK_RD();
test = cache->metadata.iface.test_out_valid(cache, line, test = ocf_metadata_test_out_valid(cache, line,
start, stop); start, stop);
OCF_METADATA_BITS_UNLOCK_RD(); OCF_METADATA_BITS_UNLOCK_RD();
@ -374,7 +388,7 @@ static inline bool metadata_set_valid_sec_changed(
bool was_any_valid; bool was_any_valid;
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
was_any_valid = cache->metadata.iface.set_valid(cache, line, was_any_valid = ocf_metadata_set_valid(cache, line,
start, stop); start, stop);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
@ -385,7 +399,7 @@ static inline void metadata_clear_valid_sec(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop) ocf_cache_line_t line, uint8_t start, uint8_t stop)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.clear_valid(cache, line, start, stop); ocf_metadata_clear_valid(cache, line, start, stop);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
} }
@ -393,7 +407,7 @@ static inline void metadata_clear_valid_sec_one(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t pos) ocf_cache_line_t line, uint8_t pos)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.clear_valid(cache, line, pos, pos); ocf_metadata_clear_valid(cache, line, pos, pos);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
} }
@ -401,7 +415,7 @@ static inline void metadata_set_valid_sec_one(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t pos) ocf_cache_line_t line, uint8_t pos)
{ {
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
cache->metadata.iface.set_valid(cache, line, pos, pos); ocf_metadata_set_valid(cache, line, pos, pos);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
} }
/* /*
@ -419,11 +433,11 @@ static inline bool metadata_clear_valid_sec_changed(
OCF_METADATA_BITS_LOCK_WR(); OCF_METADATA_BITS_LOCK_WR();
was_any_valid = cache->metadata.iface.test_valid(cache, line, was_any_valid = ocf_metadata_test_valid(cache, line,
cache->metadata.settings.sector_start, cache->metadata.settings.sector_start,
cache->metadata.settings.sector_end, false); cache->metadata.settings.sector_end, false);
*is_valid = cache->metadata.iface.clear_valid(cache, line, *is_valid = ocf_metadata_clear_valid(cache, line,
start, stop); start, stop);
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();

View File

@ -26,53 +26,6 @@ enum ocf_metadata_shutdown_status {
ocf_metadata_detached = 2, /*!< Cache device detached */ ocf_metadata_detached = 2, /*!< Cache device detached */
}; };
/*
* Metadata cache line location on pages interface
*/
struct ocf_metadata_layout_iface {
/**
* This function is mapping collision index to appropriate cache line
* (logical cache line to physical one mapping).
*
* It is necessary because we want to generate sequential workload with
* data to cache device.
* Our collision list, for example, looks:
* 0 3 6 9
* 1 4 7 10
* 2 5 8
* All collision index in each column is on the same page
* on cache device. We don't want send request x times to the same
* page. To don't do it we use collision index by row, but in this
* case we can't use collision index directly as cache line,
* because we will generate non sequential workload (we will write
* pages: 0 -> 3 -> 6 ...). To map collision index in correct way
* we use this function.
*
* After use this function, collision index in the above array
* corresponds with below cache line:
* 0 1 2 3
* 4 5 6 7
* 8 9 10
*
* @param cache - cache instance
* @param idx - index in collision list
* @return mapped cache line
*/
ocf_cache_line_t (*lg2phy)(struct ocf_cache *cache,
ocf_cache_line_t coll_idx);
/**
* @brief Map physical cache line on cache device to logical one
* @note This function is the inverse of map_coll_idx_to_cache_line
*
* @param cache Cache instance
* @param phy Physical cache line of cache device
* @return Logical cache line
*/
ocf_cache_line_t (*phy2lg)(struct ocf_cache *cache,
ocf_cache_line_t phy);
};
/** /**
* @brief Query cores completion callback * @brief Query cores completion callback
* *
@ -83,324 +36,6 @@ struct ocf_metadata_layout_iface {
typedef void (*ocf_metadata_query_cores_end_t)(void *priv, int error, typedef void (*ocf_metadata_query_cores_end_t)(void *priv, int error,
unsigned int num_cores); unsigned int num_cores);
/**
* OCF Metadata interface
*/
struct ocf_metadata_iface {
/**
* @brief Initialize metadata
*
* @param cache - Cache instance
* @param cache_line_size - Cache line size
* @return 0 - Operation success otherwise failure
*/
int (*init)(struct ocf_cache *cache,
ocf_cache_line_size_t cache_line_size);
/**
* @brief Initialize variable size metadata sections
*
* @param cache - Cache instance
* @param device_size - Cache size in bytes
* @param cache_line_size - Cache line size
* @param layout Metadata layout
* @return 0 - Operation success otherwise failure
*/
int (*init_variable_size)(struct ocf_cache *cache, uint64_t device_size,
ocf_cache_line_size_t cache_line_size,
ocf_metadata_layout_t layout);
/**
* @brief Query metadata for added cores
*
* @param[in] owner - OCF context
* @param[in] volume - volume to probe
* @param[in,out] uuid - array of uuids
* @param[in] count - size of uuid array
* @param[in] cmpl - completion callback
* @param[in] priv - completion private data
*/
void (*query_cores)(ocf_ctx_t owner, ocf_volume_t volume,
struct ocf_volume_uuid *uuid, uint32_t count,
ocf_metadata_query_cores_end_t cmpl, void *priv);
/**
* @brief Metadata cache line location on pages interface
*/
const struct ocf_metadata_layout_iface *layout_iface;
/**
* @brief Initialize hash table
*
* @param cache - Cache instance
*/
void (*init_hash_table)(struct ocf_cache *cache);
/**
* @brief Initialize collision table
*
* @param cache - Cache instance
*/
void (*init_collision)(struct ocf_cache *cache);
/**
* @brief De-Initialize metadata
*
* @param cache - Cache instance
*/
void (*deinit)(struct ocf_cache *cache);
/**
* @brief De-Initialize variable size metadata segments
*
* @param cache - Cache instance
*/
void (*deinit_variable_size)(struct ocf_cache *cache);
/**
* @brief Get memory footprint
*
* @param cache - Cache instance
* @return 0 - memory footprint
*/
size_t (*size_of)(struct ocf_cache *cache);
/**
* @brief Get amount of pages required for metadata
*
* @param cache - Cache instance
* @return Pages required for store metadata on cache device
*/
ocf_cache_line_t (*pages)(struct ocf_cache *cache);
/**
* @brief Get amount of cache lines
*
* @param cache - Cache instance
* @return Amount of cache lines (cache device lines - metadata space)
*/
ocf_cache_line_t (*cachelines)(struct ocf_cache *cache);
/**
* @brief Load metadata from cache device
*
* @param[in] cache - Cache instance
* @param[in] cmpl - Completion callback
* @param[in] priv - Completion callback context
*/
void (*load_all)(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);
/**
* @brief Load metadata from recovery procedure
*
* @param[in] cache - Cache instance
* @param[in] cmpl - Completion callback
* @param[in] priv - Completion callback context
*/
void (*load_recovery)(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);
/**
* @brief Flush metadata into cahce cache
*
* @param[in] cache - Cache instance
* @param[in] cmpl - Completion callback
* @param[in] priv - Completion callback context
*/
void (*flush_all)(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);
/**
* @brief Mark specified cache line to be flushed
*
* @param[in] cache - Cache instance
* @param[in] line - cache line which to be flushed
*/
void (*flush_mark)(struct ocf_cache *cache, struct ocf_request *req,
uint32_t map_idx, int to_state, uint8_t start,
uint8_t stop);
/**
* @brief Flush marked cache lines asynchronously
*
* @param cache - Cache instance
* @param queue - I/O queue to which metadata flush should be submitted
* @param remaining - request remaining
* @param complete - flushing request callback
* @param context - context that will be passed into callback
*/
void (*flush_do_asynch)(struct ocf_cache *cache,
struct ocf_request *req, ocf_req_end_t complete);
/* TODO Provide documentation below */
enum ocf_metadata_shutdown_status (*get_shutdown_status)(
struct ocf_cache *cache);
void (*set_shutdown_status)(ocf_cache_t cache,
enum ocf_metadata_shutdown_status shutdown_status,
ocf_metadata_end_t cmpl, void *priv);
void (*load_superblock)(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);
void (*flush_superblock)(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);
uint64_t (*get_reserved_lba)(struct ocf_cache *cache);
/**
* @brief Get eviction policy
*
* @param[in] cache - Cache instance
* @param[in] line - cache line for which eviction policy is requested
* @return eviction policy metadata
*/
union eviction_policy_meta *(*get_eviction_policy)(
struct ocf_cache *cache, ocf_cache_line_t line);
/**
* @brief Get cleaning policy
*
* @param[in] cache - Cache instance
* @param[in] line - cache line for which cleaning policy is requested
* @return cleaning_policy metadata
*/
struct cleaning_policy_meta *(*get_cleaning_policy)(
struct ocf_cache *cache, ocf_cache_line_t line);
/**
* @brief Get hash table for specified index
*
* @param[in] cache - Cache instance
* @param[in] index - Hash table index
* @return Cache line value under specified hash table index
*/
ocf_cache_line_t (*get_hash)(struct ocf_cache *cache,
ocf_cache_line_t index);
/**
* @brief Set hash table value for specified index
*
* @param[in] cache - Cache instance
* @param[in] index - Hash table index
* @param[in] line - Cache line value to be set under specified hash
* table index
*/
void (*set_hash)(struct ocf_cache *cache,
ocf_cache_line_t index, ocf_cache_line_t line);
/**
* @brief Get hash table entries
*
* @param[in] cache - Cache instance
* @return Hash table entries
*/
ocf_cache_line_t (*entries_hash)(struct ocf_cache *cache);
/* TODO Provide documentation below */
void (*set_core_info)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_core_id_t core_id,
uint64_t core_sector);
void (*get_core_info)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_core_id_t *core_id,
uint64_t *core_sector);
ocf_core_id_t (*get_core_id)(struct ocf_cache *cache,
ocf_cache_line_t line);
void (*get_core_and_part_id)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_core_id_t *core_id,
ocf_part_id_t *part_id);
struct ocf_metadata_uuid *(*get_core_uuid)(
struct ocf_cache *cache, ocf_core_id_t core_id);
void (*set_collision_info)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t next,
ocf_cache_line_t prev);
void (*get_collision_info)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t *next,
ocf_cache_line_t *prev);
void (*set_collision_next)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t next);
void (*set_collision_prev)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t prev);
void (*start_collision_shared_access)(struct ocf_cache *cache,
ocf_cache_line_t line);
void (*end_collision_shared_access)(struct ocf_cache *cache,
ocf_cache_line_t line);
void (*get_partition_info)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_part_id_t *part_id,
ocf_cache_line_t *next_line,
ocf_cache_line_t *prev_line);
void (*set_partition_next)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t next_line);
void (*set_partition_prev)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_cache_line_t prev_line);
void (*set_partition_info)(struct ocf_cache *cache,
ocf_cache_line_t line, ocf_part_id_t part_id,
ocf_cache_line_t next_line, ocf_cache_line_t prev_line);
const struct ocf_metadata_status*
(*rd_status_access)(struct ocf_cache *cache,
ocf_cache_line_t line);
struct ocf_metadata_status*
(*wr_status_access)(struct ocf_cache *cache,
ocf_cache_line_t line);
bool (*test_dirty)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
bool (*test_out_dirty)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool (*clear_dirty)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool (*set_dirty)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool (*test_and_set_dirty)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
bool (*test_and_clear_dirty)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
bool (*test_valid)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
bool (*test_out_valid)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool (*clear_valid)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool (*set_valid)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop);
bool (*test_and_set_valid)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
bool (*test_and_clear_valid)(struct ocf_cache *cache,
ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all);
};
struct ocf_cache_line_settings { struct ocf_cache_line_settings {
ocf_cache_line_size_t size; ocf_cache_line_size_t size;
uint64_t sector_count; uint64_t sector_count;
@ -425,10 +60,10 @@ struct ocf_metadata_lock
* @brief Metadata control structure * @brief Metadata control structure
*/ */
struct ocf_metadata { struct ocf_metadata {
const struct ocf_metadata_iface iface; ocf_metadata_layout_t layout;
/*!< Metadata service interface */ /*!< Per-cacheline metadata layout */
void *iface_priv; void *priv;
/*!< Private data of metadata service interface */ /*!< Private data of metadata service interface */
const struct ocf_cache_line_settings settings; const struct ocf_cache_line_settings settings;

View File

@ -0,0 +1,505 @@
/*
* Copyright(c) 2020 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include "metadata.h"
#include "metadata_core.h"
#include "metadata_internal.h"
#include "metadata_segment_id.h"
#include "metadata_superblock.h"
#include "../ocf_priv.h"
#include "../utils/utils_io.h"
#define OCF_METADATA_SUPERBLOCK_DEBUG 0
#if 1 == OCF_METADATA_SUPERBLOCK_DEBUG
#define OCF_DEBUG_TRACE(cache) \
ocf_cache_log(cache, log_info, "[Metadata][Superblock] %s\n", \
__func__)
#define OCF_DEBUG_PARAM(cache, format, ...) \
ocf_cache_log(cache, log_info, "[Metadata][Superblock] %s - " \
format"\n", __func__, ##__VA_ARGS__)
#else
#define OCF_DEBUG_TRACE(cache)
#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
*
* @param shutdown_status - status to be assigned to cache.
*
* @return Operation status (0 success, otherwise error)
*/
void ocf_metadata_set_shutdown_status(ocf_cache_t cache,
enum ocf_metadata_shutdown_status shutdown_status,
ocf_metadata_end_t cmpl, void *priv)
{
struct ocf_metadata_ctrl *ctrl;
struct ocf_superblock_config *superblock;
OCF_DEBUG_TRACE(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 = ocf_metadata_raw_get_mem(
&ctrl->raw_desc[metadata_segment_sb_config]);
/* Set shutdown status */
superblock->clean_shutdown = shutdown_status;
superblock->magic_number = CACHE_MAGIC_NUMBER;
/* Flush superblock */
ocf_metadata_flush_superblock(cache, cmpl, priv);
}
static void ocf_metadata_store_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;
ocf_cache_t cache = context->cache;
int error;
ctrl = (struct ocf_metadata_ctrl *)cache->metadata.priv;
context->segment_copy[segment].mem_pool =
env_malloc(ctrl->raw_desc[segment].mem_pool_limit, ENV_MEM_NORMAL);
if (!context->segment_copy[segment].mem_pool)
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_NO_MEM);
error = env_memcpy(context->segment_copy[segment].mem_pool,
ctrl->raw_desc[segment].mem_pool_limit, METADATA_MEM_POOL(ctrl, segment),
ctrl->raw_desc[segment].mem_pool_limit);
if (error) {
env_free(context->segment_copy[segment].mem_pool);
context->segment_copy[segment].mem_pool = NULL;
OCF_PL_FINISH_RET(pipeline, error);
}
ocf_pipeline_next(pipeline);
}
static void ocf_metadata_check_crc_sb_config(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;
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",
ocf_metadata_segment_names[segment]);
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL);
}
ocf_pipeline_next(pipeline);
}
static void ocf_metadata_load_superblock_post(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_metadata_uuid *muuid;
struct ocf_volume_uuid uuid;
ocf_volume_type_t volume_type;
ocf_core_t core;
ocf_core_id_t core_id;
ctrl = (struct ocf_metadata_ctrl *)cache->metadata.priv;
sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config);
for_each_core_metadata(cache, core, core_id) {
muuid = ocf_metadata_get_core_uuid(cache, core_id);
uuid.data = muuid->data;
uuid.size = muuid->size;
volume_type = ocf_ctx_get_volume_type(cache->owner,
core->conf_meta->type);
/* Initialize core volume */
ocf_volume_init(&core->volume, volume_type, &uuid, false);
core->has_volume = true;
}
/* Restore all dynamics items */
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_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);
}
ocf_pipeline_next(pipeline);
}
static void ocf_metadata_load_sb_restore(
struct ocf_metadata_context *context)
{
ocf_cache_t cache = context->cache;
struct ocf_metadata_ctrl *ctrl;
int segment, error;
ctrl = (struct ocf_metadata_ctrl *)cache->metadata.priv;
for (segment = metadata_segment_sb_config;
segment < metadata_segment_fixed_size_max; segment++) {
if (!context->segment_copy[segment].mem_pool)
continue;
error = env_memcpy(METADATA_MEM_POOL(ctrl, segment),
ctrl->raw_desc[segment].mem_pool_limit,
context->segment_copy[segment].mem_pool,
ctrl->raw_desc[segment].mem_pool_limit);
ENV_BUG_ON(error);
}
}
static void ocf_metadata_load_superblock_finish(ocf_pipeline_t pipeline,
void *priv, int error)
{
struct ocf_metadata_context *context = priv;
ocf_cache_t cache = context->cache;
int segment;
if (error) {
ocf_cache_log(cache, log_err, "Metadata read FAILURE\n");
ocf_metadata_error(cache);
ocf_metadata_load_sb_restore(context);
}
for (segment = metadata_segment_sb_config;
segment < metadata_segment_fixed_size_max; segment++) {
if (context->segment_copy[segment].mem_pool)
env_free(context->segment_copy[segment].mem_pool);
}
context->cmpl(context->priv, error);
ocf_pipeline_destroy(pipeline);
}
struct ocf_pipeline_arg ocf_metadata_load_sb_store_segment_args[] = {
OCF_PL_ARG_INT(metadata_segment_sb_config),
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_TERMINATOR(),
};
struct ocf_pipeline_arg ocf_metadata_load_sb_load_segment_args[] = {
OCF_PL_ARG_INT(metadata_segment_sb_config),
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_load_sb_check_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_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_load_sb_pipeline_props = {
.priv_size = sizeof(struct ocf_metadata_context),
.finish = ocf_metadata_load_superblock_finish,
.steps = {
OCF_PL_STEP_FOREACH(ocf_metadata_store_segment,
ocf_metadata_load_sb_store_segment_args),
OCF_PL_STEP_FOREACH(ocf_metadata_load_segment,
ocf_metadata_load_sb_load_segment_args),
OCF_PL_STEP(ocf_metadata_check_crc_sb_config),
OCF_PL_STEP_FOREACH(ocf_metadata_check_crc,
ocf_metadata_load_sb_check_crc_args),
OCF_PL_STEP_FOREACH(ocf_metadata_check_crc_if_clean,
ocf_metadata_load_sb_check_crc_args_clean),
OCF_PL_STEP(ocf_metadata_load_superblock_post),
OCF_PL_STEP_TERMINATOR(),
},
};
/*
* Super Block - Load, This function has to prevent to pointers overwrite
*/
void ocf_metadata_load_superblock(ocf_cache_t cache, ocf_metadata_end_t cmpl,
void *priv)
{
struct ocf_metadata_context *context;
ocf_pipeline_t pipeline;
struct ocf_metadata_ctrl *ctrl;
struct ocf_superblock_config *sb_config;
struct ocf_superblock_runtime *sb_runtime;
int result;
OCF_DEBUG_TRACE(cache);
/* 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);
ENV_BUG_ON(!sb_config);
sb_runtime = METADATA_MEM_POOL(ctrl, metadata_segment_sb_runtime);
ENV_BUG_ON(!sb_runtime);
result = ocf_pipeline_create(&pipeline, cache,
&ocf_metadata_load_sb_pipeline_props);
if (result)
OCF_CMPL_RET(priv, result);
context = ocf_pipeline_get_priv(pipeline);
context->cmpl = cmpl;
context->priv = priv;
context->pipeline = pipeline;
context->cache = cache;
context->ctrl = cache->metadata.priv;
ocf_pipeline_next(pipeline);
}
static void ocf_metadata_flush_superblock_prepare(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_metadata_context *context = priv;
ocf_cache_t cache = context->cache;
ocf_core_t core;
ocf_core_id_t core_id;
/* Synchronize core objects types */
for_each_core_metadata(cache, core, core_id) {
core->conf_meta->type = ocf_ctx_get_volume_type_id(
cache->owner, core->volume.type);
}
ocf_pipeline_next(pipeline);
}
static void ocf_metadata_calculate_crc_sb_config(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;
ctrl = context->ctrl;
sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config);
sb_config->checksum[metadata_segment_sb_config] = env_crc32(0,
(void *)sb_config,
offsetof(struct ocf_superblock_config, checksum));
ocf_pipeline_next(pipeline);
}
static void ocf_metadata_flush_superblock_finish(ocf_pipeline_t pipeline,
void *priv, int error)
{
struct ocf_metadata_context *context = priv;
ocf_cache_t cache = context->cache;
if (error)
ocf_metadata_error(cache);
context->cmpl(context->priv, error);
ocf_pipeline_destroy(pipeline);
}
static void ocf_metadata_flush_disk_end(void *priv, int error)
{
struct ocf_metadata_context *context = priv;
ocf_pipeline_t pipeline = context->pipeline;
if (error) {
OCF_PL_FINISH_RET(pipeline, error);
return;
}
ocf_pipeline_next(pipeline);
}
static void ocf_metadata_flush_disk(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_metadata_context *context = priv;
ocf_cache_t cache = context->cache;
ocf_submit_volume_flush(ocf_cache_get_volume(cache),
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),
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_properties ocf_metadata_flush_sb_pipeline_props = {
.priv_size = sizeof(struct ocf_metadata_context),
.finish = ocf_metadata_flush_superblock_finish,
.steps = {
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_PL_STEP_FOREACH(ocf_metadata_flush_segment,
ocf_metadata_flush_sb_flush_segment_args),
OCF_PL_STEP(ocf_metadata_flush_disk),
OCF_PL_STEP_TERMINATOR(),
},
};
/*
* Super Block - FLUSH
*/
void ocf_metadata_flush_superblock(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv)
{
struct ocf_metadata_context *context;
ocf_pipeline_t pipeline;
int result;
OCF_DEBUG_TRACE(cache);
result = ocf_pipeline_create(&pipeline, cache,
&ocf_metadata_flush_sb_pipeline_props);
if (result)
OCF_CMPL_RET(priv, result);
context = ocf_pipeline_get_priv(pipeline);
context->cmpl = cmpl;
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

@ -7,6 +7,7 @@
#define __METADATA_SUPERBLOCK_H__ #define __METADATA_SUPERBLOCK_H__
#include <ocf/ocf_def.h> #include <ocf/ocf_def.h>
#include "metadata_segment.h"
#define CACHE_MAGIC_NUMBER 0x187E1CA6 #define CACHE_MAGIC_NUMBER 0x187E1CA6
@ -63,24 +64,37 @@ struct ocf_superblock_runtime {
uint32_t cleaning_thread_access; uint32_t cleaning_thread_access;
}; };
static inline void ocf_metadata_set_shutdown_status(ocf_cache_t cache, struct ocf_metadata_ctrl;
void ocf_metadata_set_shutdown_status(ocf_cache_t cache,
enum ocf_metadata_shutdown_status shutdown_status, enum ocf_metadata_shutdown_status shutdown_status,
ocf_metadata_end_t cmpl, void *priv) ocf_metadata_end_t cmpl, void *priv);
{
cache->metadata.iface.set_shutdown_status(cache, shutdown_status,
cmpl, priv);
}
static inline void ocf_metadata_load_superblock(ocf_cache_t cache, void ocf_metadata_load_superblock(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv) ocf_metadata_end_t cmpl, void *priv);
{
cache->metadata.iface.load_superblock(cache, cmpl, priv);
}
static inline void ocf_metadata_flush_superblock(ocf_cache_t cache, void ocf_metadata_flush_superblock(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv) ocf_metadata_end_t cmpl, void *priv);
{
cache->metadata.iface.flush_superblock(cache, cmpl, 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_ */ #endif /* METADATA_SUPERBLOCK_H_ */