ocf/src/metadata/metadata_structs.h
Robert Baldyga 3108f36e42 Simplify collision matadata interface
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
2019-08-03 20:04:23 +02:00

465 lines
13 KiB
C

/*
* Copyright(c) 2012-2018 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef __METADATA_STRUCTS_H__
#define __METADATA_STRUCTS_H__
#include "metadata_common.h"
#include "../eviction/eviction.h"
#include "../cleaning/cleaning.h"
#include "../ocf_request.h"
/**
* @file metadata_priv.h
* @brief Metadata private structures
*/
/**
* @brief Metadata shutdown status
*/
enum ocf_metadata_shutdown_status {
ocf_metadata_clean_shutdown = 1, /*!< OCF shutdown graceful*/
ocf_metadata_dirty_shutdown = 0, /*!< Dirty OCF shutdown*/
ocf_metadata_detached = 2, /*!< Cache device detached */
};
/*
* Metadata cache line location on pages interface
*/
struct ocf_metadata_layout_iface {
/**
* @brief Initialize freelist partition
*
* @param cache - Cache instance
*/
void (*init_freelist)(struct ocf_cache *cache);
/**
* 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
*
* @param priv - Caller private data
* @param error - Operation error status
* @param num_cores - Number of cores in metadata
*/
typedef void (*ocf_metadata_query_cores_end_t)(void *priv, int error,
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 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
* @param[out] eviction_policy - Eviction policy
*/
void (*get_eviction_policy)(struct ocf_cache *cache,
ocf_cache_line_t line,
union eviction_policy_meta *eviction_policy);
/**
* @brief Set eviction policy
*
* @param[in] cache - Cache instance
* @param[in] line - Eviction policy values which will be stored in
* metadata service
* @param[out] eviction_policy - Eviction policy
*/
void (*set_eviction_policy)(struct ocf_cache *cache,
ocf_cache_line_t line,
union eviction_policy_meta *eviction_policy);
/**
* @brief Get cleaning policy
*
* @param[in] cache - Cache instance
* @param[in] line - cache line for which cleaning policy is requested
* @param[out] cleaning_policy - Cleaning policy
*/
void (*get_cleaning_policy)(struct ocf_cache *cache,
ocf_cache_line_t line,
struct cleaning_policy_meta *cleaning_policy);
/**
* @brief Set cleaning policy
*
* @param[in] cache - Cache instance
* @param[in] line
* @param[in] cleaning_policy - Cleaning policy values which will be
* stored in metadata service
*/
void (*set_cleaning_policy)(struct ocf_cache *cache,
ocf_cache_line_t line,
struct cleaning_policy_meta *cleaning_policy);
/**
* @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);
ocf_part_id_t (*get_partition_id)(struct ocf_cache *cache,
ocf_cache_line_t line);
ocf_cache_line_t (*get_partition_next)(struct ocf_cache *cache,
ocf_cache_line_t line);
ocf_cache_line_t (*get_partition_prev)(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 {
ocf_cache_line_size_t size;
uint64_t sector_count;
uint64_t sector_start;
uint64_t sector_end;
};
/**
* @brief Metadata control structure
*/
struct ocf_metadata {
const struct ocf_metadata_iface iface;
/*!< Metadata service interface */
void *iface_priv;
/*!< Private data of metadata service interface */
const struct ocf_cache_line_settings settings;
/*!< Cache line configuration */
bool is_volatile;
/*!< true if metadata used in volatile mode (RAM only) */
struct {
env_rwsem collision; /*!< lock for collision table */
env_rwlock status; /*!< Fast lock for status bits */
env_spinlock eviction; /*!< Fast lock for eviction policy */
} lock;
};
#endif /* __METADATA_STRUCTS_H__ */