Initial commit
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
49
inc/cleaning/acp.h
Normal file
49
inc/cleaning/acp.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
#ifndef __OCF_CLEANING_ACP_H__
|
||||
#define __OCF_CLEANING_ACP_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief ACP cleaning policy API
|
||||
*/
|
||||
|
||||
enum ocf_cleaning_acp_parameters {
|
||||
ocf_acp_wake_up_time,
|
||||
ocf_acp_flush_max_buffers,
|
||||
};
|
||||
|
||||
/**
|
||||
* @name ACP cleaning policy parameters
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* ACP cleaning policy time between flushing cycles (in ms)
|
||||
*/
|
||||
|
||||
/**< Wake up time minimum value */
|
||||
#define OCF_ACP_MIN_WAKE_UP 0
|
||||
/**< Wake up time maximum value */
|
||||
#define OCF_ACP_MAX_WAKE_UP 10000
|
||||
/**< Wake up time default value */
|
||||
#define OCF_ACP_DEFAULT_WAKE_UP 10
|
||||
|
||||
/**
|
||||
* ACP cleaning thread number of dirty cache lines to be flushed in one cycle
|
||||
*/
|
||||
|
||||
/** Dirty cache lines to be flushed in one cycle minimum value */
|
||||
#define OCF_ACP_MIN_FLUSH_MAX_BUFFERS 1
|
||||
/** Dirty cache lines to be flushed in one cycle maximum value */
|
||||
#define OCF_ACP_MAX_FLUSH_MAX_BUFFERS 10000
|
||||
/** Dirty cache lines to be flushed in one cycle default value */
|
||||
#define OCF_ACP_DEFAULT_FLUSH_MAX_BUFFERS 128
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* __OCF_CLEANING_ACP_H__ */
|
||||
74
inc/cleaning/alru.h
Normal file
74
inc/cleaning/alru.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
#ifndef __OCF_CLEANING_ALRU_H__
|
||||
#define __OCF_CLEANING_ALRU_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief ALRU cleaning policy API
|
||||
*/
|
||||
|
||||
enum ocf_cleaning_alru_parameters {
|
||||
ocf_alru_wake_up_time,
|
||||
ocf_alru_stale_buffer_time,
|
||||
ocf_alru_flush_max_buffers,
|
||||
ocf_alru_activity_threshold,
|
||||
};
|
||||
|
||||
/**
|
||||
* @name ALRU cleaning policy parameters
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* ALRU cleaning thread wake up time
|
||||
*/
|
||||
|
||||
/** Wake up time minimum value */
|
||||
#define OCF_ALRU_MIN_WAKE_UP 1
|
||||
/** Wake up time maximum value */
|
||||
#define OCF_ALRU_MAX_WAKE_UP 3600
|
||||
/** Wake up time default value */
|
||||
#define OCF_ALRU_DEFAULT_WAKE_UP 20
|
||||
|
||||
/**
|
||||
* ALRU cleaning thread staleness time
|
||||
*/
|
||||
|
||||
/** Staleness time minimum value */
|
||||
#define OCF_ALRU_MIN_STALENESS_TIME 1
|
||||
/** Staleness time maximum value */
|
||||
#define OCF_ALRU_MAX_STALENESS_TIME 3600
|
||||
/** Staleness time default value*/
|
||||
#define OCF_ALRU_DEFAULT_STALENESS_TIME 120
|
||||
|
||||
/**
|
||||
* ALRU cleaning thread number of dirty cache lines to be flushed in one cycle
|
||||
*/
|
||||
|
||||
/** Dirty cache lines to be flushed in one cycle minimum value */
|
||||
#define OCF_ALRU_MIN_FLUSH_MAX_BUFFERS 1
|
||||
/** Dirty cache lines to be flushed in one cycle maximum value */
|
||||
#define OCF_ALRU_MAX_FLUSH_MAX_BUFFERS 10000
|
||||
/** Dirty cache lines to be flushed in one cycle default value */
|
||||
#define OCF_ALRU_DEFAULT_FLUSH_MAX_BUFFERS 100
|
||||
|
||||
/**
|
||||
* ALRU cleaning thread cache idle time before flushing thread can start
|
||||
*/
|
||||
|
||||
/** Idle time before flushing thread can start minimum value */
|
||||
#define OCF_ALRU_MIN_ACTIVITY_THRESHOLD 500
|
||||
/** Idle time before flushing thread can start maximum value */
|
||||
#define OCF_ALRU_MAX_ACTIVITY_THRESHOLD 1000000
|
||||
/** Idle time before flushing thread can start default value */
|
||||
#define OCF_ALRU_DEFAULT_ACTIVITY_THRESHOLD 10000
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#endif /* __OCF_CLEANING_ALRU_H__ */
|
||||
37
inc/ocf.h
Normal file
37
inc/ocf.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef __OCF_H__
|
||||
#define __OCF_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Main OCF header
|
||||
* This file doesn't contain any functions or structures.
|
||||
* It's simply collective include file to allow OCF user include
|
||||
* everything at once.
|
||||
*/
|
||||
|
||||
#include "ocf_def.h"
|
||||
#include "ocf_types.h"
|
||||
#include "ocf_utilities.h"
|
||||
#include "ocf_io.h"
|
||||
#include "ocf_data_obj.h"
|
||||
#include "ocf_cache.h"
|
||||
#include "ocf_core.h"
|
||||
#include "ocf_queue.h"
|
||||
#include "ocf_cleaner.h"
|
||||
#include "cleaning/alru.h"
|
||||
#include "cleaning/acp.h"
|
||||
#include "ocf_metadata.h"
|
||||
#include "ocf_metadata_updater.h"
|
||||
#include "ocf_io_class.h"
|
||||
#include "ocf_stats.h"
|
||||
#include "ocf_stats_builder.h"
|
||||
#include "ocf_mngt.h"
|
||||
#include "ocf_ctx.h"
|
||||
#include "ocf_err.h"
|
||||
|
||||
#endif /* __OCF_H__ */
|
||||
250
inc/ocf_cache.h
Normal file
250
inc/ocf_cache.h
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __OCF_CACHE_H__
|
||||
#define __OCF_CACHE_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF cache API
|
||||
*/
|
||||
|
||||
#include "ocf_types.h"
|
||||
#include "ocf_data_obj.h"
|
||||
#include "ocf_ctx.h"
|
||||
#include "ocf_def.h"
|
||||
|
||||
/**
|
||||
* @brief Cache info: configuration, status
|
||||
*/
|
||||
struct ocf_cache_info {
|
||||
bool attached;
|
||||
/*!< True if caching cache is attached to cache */
|
||||
|
||||
uint8_t data_obj_type;
|
||||
/*!< Cache data object type */
|
||||
|
||||
uint32_t size;
|
||||
/*!< Actual cache size (in cache lines) */
|
||||
|
||||
/* Statistics of inactive cores */
|
||||
struct {
|
||||
uint32_t occupancy;
|
||||
/*!< Cache occupancy (in cache lines) */
|
||||
|
||||
uint32_t dirty;
|
||||
/*!< Dirty blocks within cache (in cache lines) */
|
||||
} inactive;
|
||||
|
||||
uint32_t occupancy;
|
||||
/*!< Actual cache occupancy (in cache lines) */
|
||||
|
||||
uint32_t dirty;
|
||||
/*!< Dirty blocks within cache (in cache lines) */
|
||||
|
||||
uint32_t dirty_initial;
|
||||
/*!< Dirty blocks within cache that where there when switching
|
||||
* out of WB mode
|
||||
*/
|
||||
|
||||
uint32_t dirty_for;
|
||||
/*!< How long there are dirty cache lines (in seconds) */
|
||||
|
||||
ocf_cache_mode_t cache_mode;
|
||||
/*!< Current cache mode */
|
||||
|
||||
/* Statistics of fallback Pass Through */
|
||||
struct {
|
||||
int error_counter;
|
||||
/*!< How many requests to cache failed because of IO error */
|
||||
|
||||
bool status;
|
||||
/*!< Current cache mode is PT,
|
||||
set as a result of reaching IO error threshold */
|
||||
} fallback_pt;
|
||||
|
||||
uint8_t state;
|
||||
/*!< Cache state (running/flushing/stopping etc...) */
|
||||
|
||||
ocf_eviction_t eviction_policy;
|
||||
/*!< Eviction policy selected */
|
||||
|
||||
ocf_cleaning_t cleaning_policy;
|
||||
/*!< Cleaning policy selected (alru/nop) */
|
||||
|
||||
ocf_cache_line_size_t cache_line_size;
|
||||
/*!< Cache line size in KiB */
|
||||
|
||||
uint32_t flushed;
|
||||
/*!< Number of block flushed in ongoing flush operation */
|
||||
|
||||
uint32_t core_count;
|
||||
/*!< Number of core devices associated with this cache */
|
||||
|
||||
uint64_t metadata_footprint;
|
||||
/*!< Metadata memory footprint (in bytes) */
|
||||
|
||||
uint32_t metadata_end_offset;
|
||||
/*!< LBA offset where metadata ends (in 4KiB blocks) */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Obtain data object from cache
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval Data object, NULL if dettached.
|
||||
*/
|
||||
ocf_data_obj_t ocf_cache_get_data_object(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Get ID of given cache object
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval Cache ID
|
||||
*/
|
||||
ocf_cache_id_t ocf_cache_get_id(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Get queue object associated with cache
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
* @param[in] id Queue id
|
||||
* @param[out] q Queue object
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Fail
|
||||
*/
|
||||
int ocf_cache_get_queue(ocf_cache_t cache, unsigned id, ocf_queue_t *q);
|
||||
|
||||
/**
|
||||
* @brief Set name of given cache object
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
* @param[in] src Source of Cache name
|
||||
* @param[in] src_size Size of src
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Fail
|
||||
*/
|
||||
int ocf_cache_set_name(ocf_cache_t cache, const char *src, size_t src_size);
|
||||
|
||||
/**
|
||||
* @brief Get name of given cache object
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval Cache name
|
||||
*/
|
||||
const char *ocf_cache_get_name(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Check is cache in incomplete state
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval 1 Cache is in incomplete state
|
||||
* @retval 0 Cache is in complete state
|
||||
*/
|
||||
bool ocf_cache_is_incomplete(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Check if caching device is attached
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval 1 Caching device is attached
|
||||
* @retval 0 Caching device is detached
|
||||
*/
|
||||
bool ocf_cache_is_device_attached(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Check if cache object is running
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval 1 Caching device is being stopped
|
||||
* @retval 0 Caching device is being stopped
|
||||
*/
|
||||
bool ocf_cache_is_running(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Get cache mode of given cache object
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval Cache mode
|
||||
*/
|
||||
ocf_cache_mode_t ocf_cache_get_mode(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Get cache line size of given cache object
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval Cache line size
|
||||
*/
|
||||
ocf_cache_line_size_t ocf_cache_get_line_size(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Convert bytes to cache lines
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
* @param[in] bytes Number of bytes
|
||||
*
|
||||
* @retval Cache lines count
|
||||
*/
|
||||
uint64_t ocf_cache_bytes_2_lines(ocf_cache_t cache, uint64_t bytes);
|
||||
|
||||
/**
|
||||
* @brief Get core count of given cache object
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval Core count
|
||||
*/
|
||||
uint32_t ocf_cache_get_core_count(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Get cache mode of given cache object
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
* @param[out] info Cache info structure
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Fail
|
||||
*/
|
||||
int ocf_cache_get_info(ocf_cache_t cache, struct ocf_cache_info *info);
|
||||
|
||||
/**
|
||||
* @brief Get UUID of data object associated with cache
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval Data object UUID, NULL if detached.
|
||||
*/
|
||||
const struct ocf_data_obj_uuid *ocf_cache_get_uuid(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Get OCF context of given cache object
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval OCF context
|
||||
*/
|
||||
ocf_ctx_t ocf_cache_get_ctx(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Get data object type id of given cache object
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
*
|
||||
* @retval data object type id, -1 if device detached
|
||||
*/
|
||||
uint8_t ocf_cache_get_type_id(ocf_cache_t cache);
|
||||
|
||||
#endif /* __OCF_CACHE_H__ */
|
||||
36
inc/ocf_cfg.h
Normal file
36
inc/ocf_cfg.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __OCF_CFG_H__
|
||||
#define __OCF_CFG_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF configuration file
|
||||
*/
|
||||
|
||||
/**
|
||||
* Configure maximum numbers of cores in cache instance
|
||||
*/
|
||||
#ifndef OCF_CONFIG_MAX_CORES
|
||||
#define OCF_CONFIG_MAX_CORES 4096
|
||||
#endif
|
||||
|
||||
/** Maximum number of IO classes that can be configured */
|
||||
#ifndef OCF_CONFIG_MAX_IO_CLASSES
|
||||
#define OCF_CONFIG_MAX_IO_CLASSES 33
|
||||
#endif
|
||||
|
||||
#if OCF_CONFIG_MAX_IO_CLASSES > 256
|
||||
#error "Limit of maximum number of IO classes exceeded"
|
||||
#endif
|
||||
|
||||
/** Enabling debug statistics */
|
||||
#ifndef OCF_CONFIG_DEBUG_STATS
|
||||
#define OCF_CONFIG_DEBUG_STATS 0
|
||||
#endif
|
||||
|
||||
#endif /* __OCF_CFG_H__ */
|
||||
51
inc/ocf_cleaner.h
Normal file
51
inc/ocf_cleaner.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef OCF_CLEANER_H_
|
||||
#define OCF_CLEANER_H_
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF cleaner API for synchronization dirty data
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Run cleaner
|
||||
*
|
||||
* @param[in] c Cleaner instance to run
|
||||
* @param[in] io_queue I/O queue to which cleaner requests should be submitted
|
||||
*
|
||||
* @retval Hint when to run cleaner next time. Value expressed in miliseconds.
|
||||
*/
|
||||
uint32_t ocf_cleaner_run(ocf_cleaner_t c, uint32_t io_queue);
|
||||
|
||||
/**
|
||||
* @brief Set cleaner private data
|
||||
*
|
||||
* @param[in] c Cleaner handle
|
||||
* @param[in] priv Private data
|
||||
*/
|
||||
void ocf_cleaner_set_priv(ocf_cleaner_t c, void *priv);
|
||||
|
||||
/**
|
||||
* @brief Get cleaner private data
|
||||
*
|
||||
* @param[in] c Cleaner handle
|
||||
*
|
||||
* @retval Cleaner private data
|
||||
*/
|
||||
void *ocf_cleaner_get_priv(ocf_cleaner_t c);
|
||||
|
||||
/**
|
||||
* @brief Get cache instance to which cleaner belongs
|
||||
*
|
||||
* @param[in] c Cleaner handle
|
||||
*
|
||||
* @retval Cache instance
|
||||
*/
|
||||
ocf_cache_t ocf_cleaner_get_cache(ocf_cleaner_t c);
|
||||
|
||||
#endif
|
||||
242
inc/ocf_core.h
Normal file
242
inc/ocf_core.h
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF core API
|
||||
*/
|
||||
|
||||
#ifndef __OCF_CORE_H__
|
||||
#define __OCF_CORE_H__
|
||||
|
||||
#include "ocf_types.h"
|
||||
#include "ocf_data_obj.h"
|
||||
#include "ocf_io.h"
|
||||
#include "ocf_mngt.h"
|
||||
|
||||
/**
|
||||
* @brief Obtain cache object from core
|
||||
*
|
||||
* @param[in] core Core object
|
||||
*
|
||||
* @retval Cache object
|
||||
*/
|
||||
ocf_cache_t ocf_core_get_cache(ocf_core_t core);
|
||||
|
||||
/**
|
||||
* @brief Obtain data object associated with core
|
||||
*
|
||||
* @param[in] core Core object
|
||||
*
|
||||
* @retval Data object
|
||||
*/
|
||||
ocf_data_obj_t ocf_core_get_data_object(ocf_core_t core);
|
||||
|
||||
/**
|
||||
* @brief Get UUID of data object associated with core
|
||||
*
|
||||
* @param[in] core Core object
|
||||
*
|
||||
* @retval Data object UUID
|
||||
*/
|
||||
static inline const struct ocf_data_obj_uuid *ocf_core_get_uuid(ocf_core_t core)
|
||||
{
|
||||
return ocf_data_obj_get_uuid(ocf_core_get_data_object(core));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Asociate new UUID value with given core
|
||||
*
|
||||
* @param[in] core Core object
|
||||
* @param[in] uuid new core uuid
|
||||
*
|
||||
* @retval Data object UUID
|
||||
*/
|
||||
int ocf_core_set_uuid(ocf_core_t core, const struct ocf_data_obj_uuid *uuid);
|
||||
|
||||
/**
|
||||
* @brief Get sequential cutoff threshold of given core object
|
||||
*
|
||||
* @param[in] core Core object
|
||||
*
|
||||
* @retval Sequential cutoff threshold [B]
|
||||
*/
|
||||
uint32_t ocf_core_get_seq_cutoff_threshold(ocf_core_t core);
|
||||
|
||||
/**
|
||||
* @brief Get sequential cutoff policy of given core object
|
||||
*
|
||||
* @param[in] core Core object
|
||||
*
|
||||
* @retval Sequential cutoff policy
|
||||
*/
|
||||
ocf_seq_cutoff_policy ocf_core_get_seq_cutoff_policy(ocf_core_t core);
|
||||
|
||||
/**
|
||||
* @brief Get ID of given core object
|
||||
*
|
||||
* @param[in] core Core object
|
||||
*
|
||||
* @retval Core ID
|
||||
*/
|
||||
ocf_core_id_t ocf_core_get_id(ocf_core_t core);
|
||||
|
||||
/**
|
||||
* @brief Set name of given core object
|
||||
*
|
||||
* @param[in] core Core object
|
||||
* @param[in] src Source of Core name
|
||||
* @param[in] src_size Size of src
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Fail
|
||||
*/
|
||||
int ocf_core_set_name(ocf_core_t core, const char *src, size_t src_size);
|
||||
|
||||
/**
|
||||
* @brief Get name of given core object
|
||||
*
|
||||
* @param[in] core Core object
|
||||
*
|
||||
* @retval Core name
|
||||
*/
|
||||
const char *ocf_core_get_name(ocf_core_t core);
|
||||
|
||||
/**
|
||||
* @brief Get core state
|
||||
*
|
||||
* @param[in] core Core object
|
||||
*
|
||||
* @retval Core state
|
||||
*/
|
||||
ocf_core_state_t ocf_core_get_state(ocf_core_t core);
|
||||
|
||||
/**
|
||||
* @brief Obtain core object of given ID from cache
|
||||
*
|
||||
* @param[in] cache Cache object
|
||||
* @param[in] id Core ID
|
||||
* @param[out] core Core object
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Core getting failed
|
||||
*/
|
||||
int ocf_core_get(ocf_cache_t cache, ocf_core_id_t id, ocf_core_t *core);
|
||||
|
||||
/**
|
||||
* @brief Set persistent user metadata for given core
|
||||
*
|
||||
* @param[in] core Core object
|
||||
* @param[in] data User data buffer
|
||||
* @param[in] size Size of user data buffer
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Core getting failed
|
||||
*/
|
||||
int ocf_core_set_user_metadata(ocf_core_t core, void *data, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Get persistent user metadata from given core
|
||||
*
|
||||
* @param[in] core Core object
|
||||
* @param[out] data User data buffer
|
||||
* @param[in] size Size of user data buffer
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Core getting failed
|
||||
*/
|
||||
int ocf_core_get_user_metadata(ocf_core_t core, void *data, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Allocate new ocf_io
|
||||
*
|
||||
* @param[in] core Core object
|
||||
*
|
||||
* @retval ocf_io object
|
||||
*/
|
||||
struct ocf_io *ocf_new_io(ocf_core_t core);
|
||||
|
||||
/**
|
||||
* @brief Submit ocf_io
|
||||
*
|
||||
* @param[in] io IO to be submitted
|
||||
* @param[in] mode Cache mode to be enforced
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Fail
|
||||
*/
|
||||
int ocf_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode);
|
||||
|
||||
/**
|
||||
* @brief Submit ocf_io
|
||||
*
|
||||
* @param[in] io IO to be submitted
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Fail
|
||||
*/
|
||||
static inline int ocf_submit_io(struct ocf_io *io)
|
||||
{
|
||||
return ocf_submit_io_mode(io, ocf_cache_mode_none);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fast path for submitting IO. If possible, request is processed
|
||||
* immediately without adding to internal request queue
|
||||
*
|
||||
* @param[in] io IO to be submitted
|
||||
*
|
||||
* @retval 0 IO has been submitted successfully
|
||||
* @retval Non-zero Fast submit failed. Try to submit IO with ocf_submit_io()
|
||||
*/
|
||||
int ocf_submit_io_fast(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Submit ocf_io with flush command
|
||||
*
|
||||
* @param[in] io IO to be submitted
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Fail
|
||||
*/
|
||||
int ocf_submit_flush(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Submit ocf_io with discard command
|
||||
*
|
||||
* @param[in] io IO to be submitted
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Fail
|
||||
*/
|
||||
int ocf_submit_discard(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Core visitor function type which is called back when iterating over
|
||||
* cores.
|
||||
*
|
||||
* @param[in] core Core which is currently iterated (visited)
|
||||
* @param[in] cntx Visitor context
|
||||
*
|
||||
* @retval 0 continue visiting cores
|
||||
* @retval Non-zero stop iterating and return result
|
||||
*/
|
||||
typedef int (*ocf_core_visitor_t)(ocf_core_t core, void *cntx);
|
||||
|
||||
/**
|
||||
* @brief Run visitor function for each core of given cache
|
||||
*
|
||||
* @param[in] cache OCF cache instance
|
||||
* @param[in] visitor Visitor function
|
||||
* @param[in] cntx Visitor context
|
||||
* @param[in] only_opened Visit only opened cores
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Fail
|
||||
*/
|
||||
int ocf_core_visit(ocf_cache_t cache, ocf_core_visitor_t visitor, void *cntx,
|
||||
bool only_opened);
|
||||
|
||||
#endif /* __OCF_CORE_H__ */
|
||||
356
inc/ocf_ctx.h
Normal file
356
inc/ocf_ctx.h
Normal file
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef __OCF_CTX_H__
|
||||
#define __OCF_CTX_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF library context API
|
||||
*/
|
||||
|
||||
#include "ocf_types.h"
|
||||
#include "ocf_data_obj.h"
|
||||
#include "ocf_logger.h"
|
||||
|
||||
/**
|
||||
* @brief Seeking start position in environment data buffer
|
||||
*/
|
||||
typedef enum {
|
||||
ctx_data_seek_begin,
|
||||
/*!< Seeking from the beginning of environment data buffer */
|
||||
ctx_data_seek_current,
|
||||
/*!< Seeking from current position in environment data buffer */
|
||||
} ctx_data_seek_t;
|
||||
|
||||
/**
|
||||
* @brief OCF context specific operation
|
||||
*/
|
||||
struct ocf_ctx_ops {
|
||||
/**
|
||||
* @brief The name of the environment which provides platform
|
||||
* interface for cache engine
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* @name Context data buffer operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Allocate contest data buffer
|
||||
*
|
||||
* @param[in] pages The size of data buffer in pages
|
||||
*
|
||||
* @return Context data buffer
|
||||
*/
|
||||
ctx_data_t *(*data_alloc)(uint32_t pages);
|
||||
|
||||
/**
|
||||
* @brief Free context data buffer
|
||||
*
|
||||
* @param[in] data Contex data buffer which shall be freed
|
||||
*/
|
||||
void (*data_free)(ctx_data_t *data);
|
||||
|
||||
/**
|
||||
* @brief Lock context data buffer to disable swap-out
|
||||
*
|
||||
* @param[in] data Contex data buffer which shall be locked
|
||||
*
|
||||
* @retval 0 Memory locked successfully
|
||||
* @retval Non-zero Memory locking failure
|
||||
*/
|
||||
int (*data_mlock)(ctx_data_t *data);
|
||||
|
||||
/**
|
||||
* @brief Unlock context data buffer
|
||||
*
|
||||
* @param[in] data Contex data buffer which shall be unlocked
|
||||
*/
|
||||
void (*data_munlock)(ctx_data_t *data);
|
||||
|
||||
/**
|
||||
* @brief Read from environment data buffer into raw data buffer
|
||||
*
|
||||
* @param[in,out] dst Destination raw memory buffer
|
||||
* @param[in] src Source context data buffer
|
||||
* @param[in] size Number of bytes to be read
|
||||
*
|
||||
* @return Number of read bytes
|
||||
*/
|
||||
uint32_t (*data_rd)(void *dst, ctx_data_t *src, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Write raw data buffer into context data buffer
|
||||
*
|
||||
* @param[in,out] dst Destination context data buffer
|
||||
* @param[in] src Source raw memory buffer
|
||||
* @param[in] size Number of bytes to be written
|
||||
*
|
||||
* @return Number of written bytes
|
||||
*/
|
||||
uint32_t (*data_wr)(ctx_data_t *dst, const void *src, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Zero context data buffer
|
||||
*
|
||||
* @param[in,out] dst Destination context data buffer to be zeroed
|
||||
* @param[in] size Number of bytes to be zeroed
|
||||
*
|
||||
* @return Number of zeroed bytes
|
||||
*/
|
||||
uint32_t (*data_zero)(ctx_data_t *dst, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Seek read/write head in context data buffer for specified
|
||||
* offset
|
||||
*
|
||||
* @param[in,out] dst Destination context data buffer to be seek
|
||||
* @param[in] seek Seek beginning offset
|
||||
* @param[in] size Number of bytes to be seek
|
||||
*
|
||||
* @return Number of seek bytes
|
||||
*/
|
||||
uint32_t (*data_seek)(ctx_data_t *dst,
|
||||
ctx_data_seek_t seek, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Copy context data buffer content
|
||||
*
|
||||
* @param[in,out] dst Destination context data buffer
|
||||
* @param[in] src Source context data buffer
|
||||
* @param[in] to Starting offset in destination buffer
|
||||
* @param[in] from Starting offset in source buffer
|
||||
* @param[in] bytes Number of bytes to be copied
|
||||
*
|
||||
* @return Number of bytes copied
|
||||
*/
|
||||
uint64_t (*data_cpy)(ctx_data_t *dst, ctx_data_t *src,
|
||||
uint64_t to, uint64_t from, uint64_t bytes);
|
||||
|
||||
/**
|
||||
* @brief Erase content of data buffer
|
||||
*
|
||||
* @param[in] dst Contex data buffer which shall be erased
|
||||
*/
|
||||
void (*data_secure_erase)(ctx_data_t *dst);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name I/O queue operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Initialize I/O queue.
|
||||
*
|
||||
* This function should create worker, thread or any other queue
|
||||
* processing related stuff specific to given environment.
|
||||
*
|
||||
* @param[in] q I/O queue to be initialized
|
||||
*
|
||||
* @retval 0 I/O queue has been initializaed successfully
|
||||
* @retval Non-zero I/O queue initialization failure
|
||||
*/
|
||||
int (*queue_init)(ocf_queue_t q);
|
||||
|
||||
/**
|
||||
* @brief Kick I/O queue processing
|
||||
*
|
||||
* This function should inform worker, thread or any other queue
|
||||
* processing mechanism, that there are new requests in queue to
|
||||
* be processed. Processing requests inside current call is not allowed.
|
||||
*
|
||||
* @param[in] q I/O queue to be kicked
|
||||
*/
|
||||
void (*queue_kick)(ocf_queue_t q);
|
||||
|
||||
/**
|
||||
* @brief Kick I/O queue processing
|
||||
*
|
||||
* This function should inform worker, thread or any other queue
|
||||
* processing mechanism, that there are new requests in queue to
|
||||
* be processed. Kick function is allowed to process requests in current
|
||||
* call
|
||||
*
|
||||
* @param[in] q I/O queue to be kicked
|
||||
*/
|
||||
void (*queue_kick_sync)(ocf_queue_t q);
|
||||
|
||||
/**
|
||||
* @brief Stop I/O queue
|
||||
*
|
||||
* @param[in] q I/O queue beeing stopped
|
||||
*/
|
||||
void (*queue_stop)(ocf_queue_t q);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Cleaner operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Initialize cleaner.
|
||||
*
|
||||
* This function should create worker, thread, timer or any other
|
||||
* mechanism responsible for calling cleaner routine.
|
||||
*
|
||||
* @param[in] c Descriptor of cleaner to be initialized
|
||||
*
|
||||
* @retval 0 Cleaner has been initializaed successfully
|
||||
* @retval Non-zero Cleaner initialization failure
|
||||
*/
|
||||
int (*cleaner_init)(ocf_cleaner_t c);
|
||||
|
||||
/**
|
||||
* @brief Stop cleaner
|
||||
*
|
||||
* @param[in] c Descriptor of cleaner beeing stopped
|
||||
*/
|
||||
void (*cleaner_stop)(ocf_cleaner_t c);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Metadata updater operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Initialize metadata updater.
|
||||
*
|
||||
* This function should create worker, thread, timer or any other
|
||||
* mechanism responsible for calling metadata updater routine.
|
||||
*
|
||||
* @param[in] mu Handle to metadata updater to be initialized
|
||||
*
|
||||
* @retval 0 Metadata updater has been initializaed successfully
|
||||
* @retval Non-zero I/O queue initialization failure
|
||||
*/
|
||||
int (*metadata_updater_init)(ocf_metadata_updater_t mu);
|
||||
|
||||
/**
|
||||
* @brief Kick metadata updater processing
|
||||
*
|
||||
* This function should inform worker, thread or any other mechanism,
|
||||
* that there are new metadata requests to be processed.
|
||||
*
|
||||
* @param[in] mu Metadata updater to be kicked
|
||||
*/
|
||||
void (*metadata_updater_kick)(ocf_metadata_updater_t mu);
|
||||
|
||||
/**
|
||||
* @brief Stop metadata updater
|
||||
*
|
||||
* @param[in] mu Metadata updater beeing stopped
|
||||
*/
|
||||
void (*metadata_updater_stop)(ocf_metadata_updater_t mu);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Register data object interface
|
||||
*
|
||||
* @note Type of data object operations is unique and cannot be repeated.
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] properties Reference to data object properties
|
||||
* @param[in] type_id Type id of data object operations
|
||||
*
|
||||
* @retval 0 Data object operations registered successfully
|
||||
* @retval Non-zero Data object registration failure
|
||||
*/
|
||||
int ocf_ctx_register_data_obj_type(ocf_ctx_t ctx, uint8_t type_id,
|
||||
const struct ocf_data_obj_properties *properties);
|
||||
|
||||
/**
|
||||
* @brief Unregister data object interface
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] type_id Type id of data object operations
|
||||
*/
|
||||
void ocf_ctx_unregister_data_obj_type(ocf_ctx_t ctx, uint8_t type_id);
|
||||
|
||||
/**
|
||||
* @brief Get data object type operations by type id
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] type_id Type id of data object operations which were registered
|
||||
*
|
||||
* @return Data object type
|
||||
* @retval NULL When data object operations were not registered
|
||||
* for requested type
|
||||
*/
|
||||
ocf_data_obj_type_t ocf_ctx_get_data_obj_type(ocf_ctx_t ctx, uint8_t type_id);
|
||||
|
||||
/**
|
||||
* @brief Get data object type id by type
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] type Type of data object operations which were registered
|
||||
*
|
||||
* @return Data object type id
|
||||
* @retval -1 When data object operations were not registered
|
||||
* for requested type
|
||||
*/
|
||||
int ocf_ctx_get_data_obj_type_id(ocf_ctx_t ctx, ocf_data_obj_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Create data object of given type
|
||||
*
|
||||
* @param[in] ctx handle to object designating ocf context
|
||||
* @param[out] obj data object handle
|
||||
* @param[in] uuid OCF data object UUID
|
||||
* @param[in] type_id cache/core object type id
|
||||
*
|
||||
* @return Zero when success, othewise en error
|
||||
*/
|
||||
|
||||
int ocf_ctx_data_obj_create(ocf_ctx_t ctx, ocf_data_obj_t *obj,
|
||||
struct ocf_data_obj_uuid *uuid, uint8_t type_id);
|
||||
|
||||
/**
|
||||
* @brief Set OCF context logger
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] logger Structure describing logger
|
||||
*
|
||||
* @return Zero when success, otherwise an error
|
||||
*/
|
||||
int ocf_ctx_set_logger(ocf_ctx_t ctx, const struct ocf_logger *logger);
|
||||
|
||||
/**
|
||||
* @brief Initialize OCF context
|
||||
*
|
||||
* @param[out] ctx OCF context
|
||||
* @param[in] ops OCF context operations
|
||||
*
|
||||
* @return Zero when success, otherwise an error
|
||||
*/
|
||||
int ocf_ctx_init(ocf_ctx_t *ctx, const struct ocf_ctx_ops *ops);
|
||||
|
||||
/**
|
||||
* @brief De-Initialize OCF context
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
*
|
||||
* @note Precondition is stopping all cache instances
|
||||
*
|
||||
* @return Zero when success, otherwise an error
|
||||
*/
|
||||
int ocf_ctx_exit(ocf_ctx_t ctx);
|
||||
|
||||
#endif /* __OCF_CTX_H__ */
|
||||
253
inc/ocf_data_obj.h
Normal file
253
inc/ocf_data_obj.h
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef __OCF_DATA_OBJ_H__
|
||||
#define __OCF_DATA_OBJ_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF data object API
|
||||
*/
|
||||
|
||||
#include "ocf_types.h"
|
||||
|
||||
struct ocf_io;
|
||||
|
||||
/**
|
||||
* @brief OCF data object UUID maximum allowed size
|
||||
*/
|
||||
#define OCF_DATA_OBJ_UUID_MAX_SIZE (4096UL - sizeof(uint32_t))
|
||||
|
||||
/**
|
||||
* @brief OCF data object UUID
|
||||
*/
|
||||
struct ocf_data_obj_uuid {
|
||||
size_t size;
|
||||
/*!< UUID data size */
|
||||
|
||||
const void *data;
|
||||
/*!< UUID data content */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This structure describes data object capabilities
|
||||
*/
|
||||
struct ocf_data_obj_caps {
|
||||
uint32_t atomic_writes : 1;
|
||||
/*!< Data object supports atomic writes */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief OCF data object interface declaration
|
||||
*/
|
||||
struct ocf_data_obj_ops {
|
||||
/**
|
||||
* @brief Allocate new IO for this data object
|
||||
*
|
||||
* @param[in] obj Data object for which IO is created
|
||||
* @return IO On success
|
||||
* @return NULL On failure
|
||||
*/
|
||||
struct ocf_io *(*new_io)(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Submit IO on this data object
|
||||
*
|
||||
* @param[in] io IO to be submitted
|
||||
*/
|
||||
void (*submit_io)(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Submit IO with flush command
|
||||
*
|
||||
* @param[in] io IO to be submitted
|
||||
*/
|
||||
void (*submit_flush)(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Submit IO with metadata
|
||||
*
|
||||
* @param[in] io IO to be submitted
|
||||
*/
|
||||
void (*submit_metadata)(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Submit IO with discard command
|
||||
*
|
||||
* @param[in] io IO to be submitted
|
||||
*/
|
||||
void (*submit_discard)(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Submit operation to write zeroes to target address (including
|
||||
* metadata extended LBAs in atomic mode)
|
||||
*
|
||||
* @param[in] io IO description (addr, size)
|
||||
*/
|
||||
void (*submit_write_zeroes)(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Open data object
|
||||
*
|
||||
* @note This function performs data object initialization and should
|
||||
* be called before any other operation on data object
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
*/
|
||||
int (*open)(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Close data object
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
*/
|
||||
void (*close)(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Close data object
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
*/
|
||||
unsigned int (*get_max_io_size)(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Close data object
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
*/
|
||||
uint64_t (*get_length)(ocf_data_obj_t obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This structure describes data object properties
|
||||
*/
|
||||
struct ocf_data_obj_properties {
|
||||
const char *name;
|
||||
/*!< The name of data object operations */
|
||||
|
||||
uint32_t io_context_size;
|
||||
/*!< Size of io context structure */
|
||||
|
||||
struct ocf_data_obj_caps caps;
|
||||
/*!< Data object capabilities */
|
||||
|
||||
struct ocf_data_obj_ops ops;
|
||||
/*!< Data object operations */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get data object type
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
*
|
||||
* @return Data object type
|
||||
*/
|
||||
ocf_data_obj_type_t ocf_data_obj_get_type(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Get private context of data object
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
*
|
||||
* @return Data object private context
|
||||
*/
|
||||
void *ocf_data_obj_get_priv(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Set private context for data object
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
* @param[in] priv Data object private context to be set
|
||||
*/
|
||||
void ocf_data_obj_set_priv(ocf_data_obj_t obj, void *priv);
|
||||
|
||||
/**
|
||||
* @brief Get data object UUID
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
*
|
||||
* @return UUID of data object
|
||||
*/
|
||||
const struct ocf_data_obj_uuid *ocf_data_obj_get_uuid(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Get data object length
|
||||
*
|
||||
* @param[in] obj Data object
|
||||
*
|
||||
* @return Length of data object in bytes
|
||||
*/
|
||||
uint64_t ocf_data_obj_get_length(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Get cache handle for given data object
|
||||
*
|
||||
* @param obj data object handle
|
||||
*
|
||||
* @return Handle to cache for which data object belongs to
|
||||
*/
|
||||
ocf_cache_t ocf_data_obj_get_cache(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Initialize data object
|
||||
*
|
||||
* @param[in] obj data object handle
|
||||
* @param[in] type cache/core object type
|
||||
* @param[in] uuid OCF data object UUID
|
||||
* @param[in] uuid_copy crate copy of uuid data
|
||||
*
|
||||
* @return Zero when success, othewise en error
|
||||
*/
|
||||
int ocf_data_obj_init(ocf_data_obj_t obj, ocf_data_obj_type_t type,
|
||||
struct ocf_data_obj_uuid *uuid, bool uuid_copy);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize data object
|
||||
*
|
||||
* @param[in] obj data object handle
|
||||
*/
|
||||
void ocf_data_obj_deinit(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Allocate and initialize data object
|
||||
*
|
||||
* @param[out] obj pointer to data object handle
|
||||
* @param[in] type cache/core object type
|
||||
* @param[in] uuid OCF data object UUID
|
||||
*
|
||||
* @return Zero when success, othewise en error
|
||||
*/
|
||||
int ocf_data_obj_create(ocf_data_obj_t *obj, ocf_data_obj_type_t type,
|
||||
struct ocf_data_obj_uuid *uuid);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize and free data object
|
||||
*
|
||||
* @param[in] obj data object handle
|
||||
*/
|
||||
void ocf_data_obj_destroy(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Allocate new io from data object allocator
|
||||
*
|
||||
* @param[in] obj data object handle
|
||||
*/
|
||||
struct ocf_io *ocf_data_obj_new_io(ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Delete io from data object allocator
|
||||
*
|
||||
* @param[in] io handle to previously allocated io
|
||||
*/
|
||||
void ocf_data_obj_del_io(struct ocf_io* io);
|
||||
|
||||
/**
|
||||
* @brief Return io context data
|
||||
*
|
||||
* @param[in] io ocf io handle
|
||||
*/
|
||||
void *ocf_data_obj_get_data_from_io(struct ocf_io* io);
|
||||
|
||||
#endif /* __OCF_DATA_OBJ_H__ */
|
||||
325
inc/ocf_def.h
Normal file
325
inc/ocf_def.h
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __OCF_DEF_H__
|
||||
#define __OCF_DEF_H__
|
||||
|
||||
#include "ocf_cfg.h"
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF definitions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name OCF cache definitions
|
||||
*/
|
||||
/**
|
||||
* Minimum value of a valid cache ID
|
||||
*/
|
||||
#define OCF_CACHE_ID_MIN 1
|
||||
/**
|
||||
* Maximum value of a valid cache ID
|
||||
*/
|
||||
#define OCF_CACHE_ID_MAX 16384
|
||||
/**
|
||||
* Invalid value of cache id
|
||||
*/
|
||||
#define OCF_CACHE_ID_INVALID 0
|
||||
/**
|
||||
* Minimum cache size in bytes
|
||||
*/
|
||||
#define OCF_CACHE_SIZE_MIN (100 * MiB)
|
||||
/**
|
||||
* Size of cache name
|
||||
*/
|
||||
#define OCF_CACHE_NAME_SIZE 32
|
||||
/**
|
||||
* Value to turn off fallback pass through
|
||||
*/
|
||||
#define OCF_CACHE_FALLBACK_PT_INACTIVE 0
|
||||
/**
|
||||
* Minimum value of io error threshold
|
||||
*/
|
||||
#define OCF_CACHE_FALLBACK_PT_MIN_ERROR_THRESHOLD \
|
||||
OCF_CACHE_FALLBACK_PT_INACTIVE
|
||||
/**
|
||||
* Maximum value of io error threshold
|
||||
*/
|
||||
#define OCF_CACHE_FALLBACK_PT_MAX_ERROR_THRESHOLD 1000000
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name OCF cores definitions
|
||||
*/
|
||||
/**
|
||||
* Maximum numbers of cores per cache instance
|
||||
*/
|
||||
#define OCF_CORE_MAX OCF_CONFIG_MAX_CORES
|
||||
/**
|
||||
* Minimum value of a valid core ID
|
||||
*/
|
||||
#define OCF_CORE_ID_MIN 0
|
||||
/**
|
||||
* Maximum value of a valid core ID
|
||||
*/
|
||||
#define OCF_CORE_ID_MAX (OCF_CORE_MAX - 1)
|
||||
/**
|
||||
* Invalid value of core id
|
||||
*/
|
||||
#define OCF_CORE_ID_INVALID OCF_CORE_MAX
|
||||
/**
|
||||
* Size of core name
|
||||
*/
|
||||
#define OCF_CORE_NAME_SIZE 32
|
||||
/**
|
||||
* Minimum value of valid core sequence number
|
||||
*/
|
||||
#define OCF_SEQ_NO_MIN 1
|
||||
/**
|
||||
* Maximum value of a valid core sequence number
|
||||
*/
|
||||
#define OCF_SEQ_NO_MAX (65535UL)
|
||||
/*
|
||||
* Invalid value of core sequence number
|
||||
*/
|
||||
#define OCF_SEQ_NO_INVALID 0
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Miscellaneous defines
|
||||
* @{
|
||||
*/
|
||||
#define KiB (1ULL << 10)
|
||||
#define MiB (1ULL << 20)
|
||||
#define GiB (1ULL << 30)
|
||||
|
||||
#if OCF_CONFIG_DEBUG_STATS == 1
|
||||
/** Macro which indicates that extended debug statistics shall be on*/
|
||||
#define OCF_DEBUG_STATS
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* This Enumerator describes OCF cache instance state
|
||||
*/
|
||||
typedef enum {
|
||||
ocf_cache_state_running = 0, //!< ocf_cache_state_running
|
||||
/*!< OCF is currently running */
|
||||
|
||||
ocf_cache_state_stopping = 1, //!< ocf_cache_state_stopping
|
||||
/*!< OCF cache instance is stopping */
|
||||
|
||||
ocf_cache_state_initializing = 2, //!< ocf_cache_state_initializing
|
||||
/*!< OCF cache instance during initialization */
|
||||
|
||||
ocf_cache_state_incomplete = 3, //!< ocf_cache_state_incomplete
|
||||
/*!< OCF cache has at least one inactive core */
|
||||
|
||||
ocf_cache_state_max //!< ocf_cache_state_max
|
||||
/*!< Stopper of cache state enumerator */
|
||||
} ocf_cache_state_t;
|
||||
|
||||
/**
|
||||
* This Enumerator describes OCF core instance state
|
||||
*/
|
||||
typedef enum {
|
||||
ocf_core_state_active = 0,
|
||||
/*!< Core is active */
|
||||
|
||||
ocf_core_state_inactive,
|
||||
/*!< Core is inactive (not attached) */
|
||||
|
||||
ocf_core_state_max,
|
||||
/*!< Stopper of core state enumerator */
|
||||
} ocf_core_state_t;
|
||||
|
||||
|
||||
/**
|
||||
* OCF supported cache modes
|
||||
*/
|
||||
typedef enum {
|
||||
ocf_cache_mode_wt = 0,
|
||||
/*!< Write-through cache mode */
|
||||
|
||||
ocf_cache_mode_wb,
|
||||
/*!< Write-back cache mode */
|
||||
|
||||
ocf_cache_mode_wa,
|
||||
/*!< Write-around cache mode */
|
||||
|
||||
ocf_cache_mode_pt,
|
||||
/*!< Pass-through cache mode */
|
||||
|
||||
ocf_cache_mode_wi,
|
||||
/*!< Write invalidate cache mode */
|
||||
|
||||
ocf_cache_mode_max,
|
||||
/*!< Stopper of cache mode enumerator */
|
||||
|
||||
ocf_cache_mode_default = ocf_cache_mode_wt,
|
||||
/*!< Default cache mode */
|
||||
|
||||
ocf_cache_mode_none = -1,
|
||||
/*!< Current cache mode of given cache instance */
|
||||
} ocf_cache_mode_t;
|
||||
|
||||
typedef enum {
|
||||
ocf_seq_cutoff_policy_always = 0,
|
||||
/*!< Sequential cutoff always on */
|
||||
|
||||
ocf_seq_cutoff_policy_full,
|
||||
/*!< Sequential cutoff when occupancy is 100% */
|
||||
|
||||
ocf_seq_cutoff_policy_never,
|
||||
/*!< Sequential cutoff disabled */
|
||||
|
||||
ocf_seq_cutoff_policy_max,
|
||||
/*!< Stopper of sequential cutoff policy enumerator */
|
||||
|
||||
ocf_seq_cutoff_policy_default = ocf_seq_cutoff_policy_full,
|
||||
/*!< Default sequential cutoff policy*/
|
||||
} ocf_seq_cutoff_policy;
|
||||
|
||||
/**
|
||||
* OCF supported eviction types
|
||||
*/
|
||||
typedef enum {
|
||||
ocf_eviction_lru = 0,
|
||||
/*!< Last recently used eviction policy */
|
||||
|
||||
ocf_eviction_max,
|
||||
/*!< Stopper of enumerator */
|
||||
|
||||
ocf_eviction_default = ocf_eviction_lru,
|
||||
/*!< Default eviction policy */
|
||||
} ocf_eviction_t;
|
||||
|
||||
/**
|
||||
* OCF supported Write-Back cleaning policies type
|
||||
*/
|
||||
typedef enum {
|
||||
ocf_cleaning_nop = 0,
|
||||
/*!< Cleaning won't happen in background. Only on eviction or
|
||||
* during cache stop
|
||||
*/
|
||||
|
||||
ocf_cleaning_alru,
|
||||
/*!< Approximately recently used. Cleaning thread in the
|
||||
* background enabled which cleans dirty data during IO
|
||||
* inactivity.
|
||||
*/
|
||||
|
||||
ocf_cleaning_acp,
|
||||
/*!< Cleaning algorithm attempts to reduce core device seek
|
||||
* distance. Cleaning thread runs concurrently with I/O.
|
||||
*/
|
||||
|
||||
ocf_cleaning_max,
|
||||
/*!< Stopper of enumerator */
|
||||
|
||||
ocf_cleaning_default = ocf_cleaning_alru,
|
||||
/*!< Default cleaning policy type */
|
||||
} ocf_cleaning_t;
|
||||
|
||||
/**
|
||||
* OCF supported cache line sizes in bytes
|
||||
*/
|
||||
typedef enum {
|
||||
ocf_cache_line_size_4 = 4 * KiB,
|
||||
/*!< 4 kiB */
|
||||
|
||||
ocf_cache_line_size_8 = 8 * KiB,
|
||||
/*!< 8 kiB */
|
||||
|
||||
ocf_cache_line_size_16 = 16 * KiB,
|
||||
/*!< 16 kiB */
|
||||
|
||||
ocf_cache_line_size_32 = 32 * KiB,
|
||||
/*!< 32 kiB */
|
||||
|
||||
ocf_cache_line_size_64 = 64 * KiB,
|
||||
/*!< 64 kiB */
|
||||
|
||||
ocf_cache_line_size_default = ocf_cache_line_size_4,
|
||||
/*!< Default cache line size */
|
||||
|
||||
ocf_cache_line_size_min = ocf_cache_line_size_4,
|
||||
/*!< Minimum cache line size */
|
||||
|
||||
ocf_cache_line_size_max = ocf_cache_line_size_64,
|
||||
/*!< Maximal cache line size */
|
||||
|
||||
ocf_cache_line_size_inf = ~0ULL,
|
||||
/*!< Force enum to be 64-bit */
|
||||
} ocf_cache_line_size_t;
|
||||
|
||||
/**
|
||||
* Metadata layout
|
||||
*/
|
||||
typedef enum {
|
||||
ocf_metadata_layout_striping = 0,
|
||||
ocf_metadata_layout_seq = 1,
|
||||
ocf_metadata_layout_max,
|
||||
ocf_metadata_layout_default = ocf_metadata_layout_striping
|
||||
} ocf_metadata_layout_t;
|
||||
|
||||
/**
|
||||
* @name OCF IO class definitions
|
||||
*/
|
||||
/**
|
||||
* Maximum numbers of IO classes per cache instance
|
||||
*/
|
||||
#define OCF_IO_CLASS_MAX OCF_CONFIG_MAX_IO_CLASSES
|
||||
/**
|
||||
* Minimum value of a valid IO class ID
|
||||
*/
|
||||
#define OCF_IO_CLASS_ID_MIN 0
|
||||
/**
|
||||
* Maximum value of a valid IO class ID
|
||||
*/
|
||||
#define OCF_IO_CLASS_ID_MAX (OCF_IO_CLASS_MAX - 1)
|
||||
/**
|
||||
* Invalid value of IO class id
|
||||
*/
|
||||
#define OCF_IO_CLASS_INVALID OCF_IO_CLASS_MAX
|
||||
|
||||
/** Maximum size of the IO class name */
|
||||
#define OCF_IO_CLASS_NAME_MAX 33
|
||||
|
||||
/** IO class priority which indicates pinning */
|
||||
#define OCF_IO_CLASS_PRIO_PINNED -1
|
||||
|
||||
/** The highest IO class priority */
|
||||
#define OCF_IO_CLASS_PRIO_HIGHEST 0
|
||||
|
||||
/** The lowest IO class priority */
|
||||
#define OCF_IO_CLASS_PRIO_LOWEST 255
|
||||
|
||||
/** Default IO class priority */
|
||||
#define OCF_IO_CLASS_PRIO_DEFAULT OCF_IO_CLASS_PRIO_LOWEST
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name I/O operations
|
||||
* @{
|
||||
*/
|
||||
#define OCF_READ 0
|
||||
#define OCF_WRITE 1
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define MAX_TRIM_RQ_SIZE (1 * MiB)
|
||||
|
||||
#endif /* __OCF_DEF_H__ */
|
||||
97
inc/ocf_err.h
Normal file
97
inc/ocf_err.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef __OCF_ERR_H__
|
||||
#define __OCF_ERR_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF error codes definitions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief OCF error enumerator
|
||||
*/
|
||||
typedef enum {
|
||||
/** Invalid input parameter value */
|
||||
OCF_ERR_INVAL = 1000000,
|
||||
|
||||
/** Invalid data object type */
|
||||
OCF_ERR_INVAL_DATA_OBJ_TYPE,
|
||||
|
||||
/** Operation interrupted */
|
||||
OCF_ERR_INTR,
|
||||
|
||||
/** Unknown error occurred */
|
||||
OCF_ERR_UNKNOWN,
|
||||
|
||||
/*!< To many caches */
|
||||
OCF_ERR_TOO_MANY_CACHES,
|
||||
|
||||
/** Out of memory */
|
||||
OCF_ERR_NO_MEM,
|
||||
|
||||
/** Not enough RAM to start cache */
|
||||
OCF_ERR_NO_FREE_RAM,
|
||||
|
||||
/** Start cache failure */
|
||||
OCF_ERR_START_CACHE_FAIL,
|
||||
|
||||
/** Cache is busy */
|
||||
OCF_ERR_CACHE_IN_USE,
|
||||
|
||||
/** Cache ID does not exist */
|
||||
OCF_ERR_CACHE_NOT_EXIST,
|
||||
|
||||
/** Cache ID already exists */
|
||||
OCF_ERR_CACHE_EXIST,
|
||||
|
||||
/** Too many core devices in cache */
|
||||
OCF_ERR_TOO_MANY_CORES,
|
||||
|
||||
/** Core device not available */
|
||||
OCF_ERR_CORE_NOT_AVAIL,
|
||||
|
||||
/** Cannot open device exclusively*/
|
||||
OCF_ERR_NOT_OPEN_EXC,
|
||||
|
||||
/** Cache device not available */
|
||||
OCF_ERR_CACHE_NOT_AVAIL,
|
||||
|
||||
/** IO Class does not exist */
|
||||
OCF_ERR_IO_CLASS_NOT_EXIST,
|
||||
|
||||
/** Error while writing to cache device */
|
||||
OCF_ERR_WRITE_CACHE,
|
||||
|
||||
/** Error while writing to core device */
|
||||
OCF_ERR_WRITE_CORE,
|
||||
|
||||
/*!< Dirty shutdown */
|
||||
OCF_ERR_DIRTY_SHUTDOWN,
|
||||
|
||||
/** Cache contains dirty data */
|
||||
OCF_ERR_DIRTY_EXISTS,
|
||||
|
||||
/** Flushing of core interrupted */
|
||||
OCF_ERR_FLUSHING_INTERRUPTED,
|
||||
|
||||
/** Adding core to core pool failed */
|
||||
OCF_ERR_CANNOT_ADD_CORE_TO_POOL,
|
||||
|
||||
/** Cache is in incomplete state */
|
||||
OCF_ERR_CACHE_IN_INCOMPLETE_STATE,
|
||||
|
||||
/** Core device is in inactive state */
|
||||
OCF_ERR_CORE_IN_INACTIVE_STATE,
|
||||
|
||||
/** Invalid cache mode */
|
||||
OCF_ERR_INVALID_CACHE_MODE,
|
||||
|
||||
/** Invalid cache line size */
|
||||
OCF_ERR_INVALID_CACHE_LINE_SIZE,
|
||||
} ocf_error_t;
|
||||
|
||||
#endif /* __OCF_ERR_H__ */
|
||||
336
inc/ocf_io.h
Normal file
336
inc/ocf_io.h
Normal file
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __OCF_IO_H__
|
||||
#define __OCF_IO_H__
|
||||
|
||||
#include "ocf_types.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF IO definitions
|
||||
*/
|
||||
|
||||
struct ocf_io;
|
||||
|
||||
/**
|
||||
* @brief OCF IO legacy completion
|
||||
*
|
||||
* @note This type of completion is for legacy completion type
|
||||
*
|
||||
* @param[in] private_data Private data for completion function
|
||||
* @param[in] error Completion status code
|
||||
*/
|
||||
typedef void (*ocf_end_t)(void *private_data, int error);
|
||||
|
||||
/**
|
||||
* @brief OCF IO start
|
||||
*
|
||||
* @note OCF IO start notification callback
|
||||
*
|
||||
* @param[in] io OCF IO being started
|
||||
*/
|
||||
typedef void (*ocf_start_io_t)(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief OCF IO handle
|
||||
*
|
||||
* @note OCF IO handle callback
|
||||
*
|
||||
* @param[in] io OCF IO to handle
|
||||
*/
|
||||
typedef void (*ocf_handle_io_t)(struct ocf_io *io, void *opaque);
|
||||
|
||||
/**
|
||||
* @brief OCF IO completion
|
||||
*
|
||||
* @note Completion function for OCF IO
|
||||
*
|
||||
* @param[in] io OCF IO being completed
|
||||
* @param[in] error Completion status code
|
||||
*/
|
||||
typedef void (*ocf_end_io_t)(struct ocf_io *io, int error);
|
||||
|
||||
/**
|
||||
* @brief OCF IO main structure
|
||||
*/
|
||||
struct ocf_io {
|
||||
/**
|
||||
* @brief OCF IO destination data object
|
||||
*/
|
||||
ocf_data_obj_t obj;
|
||||
|
||||
/**
|
||||
* @brief Operations set for this OCF IO
|
||||
*/
|
||||
const struct ocf_io_ops *ops;
|
||||
|
||||
/**
|
||||
* @brief OCF IO destination address
|
||||
*/
|
||||
uint64_t addr;
|
||||
|
||||
/**
|
||||
* @brief OCF IO flags
|
||||
*/
|
||||
uint64_t flags;
|
||||
|
||||
/**
|
||||
* @brief OCF IO size in bytes
|
||||
*/
|
||||
uint32_t bytes;
|
||||
|
||||
/**
|
||||
* @brief OCF IO destination class
|
||||
*/
|
||||
uint32_t class;
|
||||
|
||||
/**
|
||||
* @brief OCF IO direction
|
||||
*/
|
||||
uint32_t dir;
|
||||
|
||||
/**
|
||||
* @brief Queue id
|
||||
*/
|
||||
uint32_t io_queue;
|
||||
|
||||
/**
|
||||
* @brief OCF IO start function
|
||||
*/
|
||||
ocf_start_io_t start;
|
||||
|
||||
/**
|
||||
* @brief OCF IO handle function
|
||||
*/
|
||||
ocf_handle_io_t handle;
|
||||
|
||||
/**
|
||||
* @brief OCF IO completion function
|
||||
*/
|
||||
ocf_end_io_t end;
|
||||
|
||||
/**
|
||||
* @brief OCF IO private 1
|
||||
*/
|
||||
void *priv1;
|
||||
|
||||
/**
|
||||
* @brief OCF IO private 2
|
||||
*/
|
||||
void *priv2;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief OCF IO operations set structure
|
||||
*/
|
||||
struct ocf_io_ops {
|
||||
/**
|
||||
* @brief Set up data vector in OCF IO
|
||||
*
|
||||
* @param[in] io OCF IO to set up
|
||||
* @param[in] data Source context data
|
||||
* @param[in] offset Data offset in source context data
|
||||
*
|
||||
* @retval 0 Data set up successfully
|
||||
* @retval Non-zero Data set up failure
|
||||
*/
|
||||
int (*set_data)(struct ocf_io *io, ctx_data_t *data,
|
||||
uint32_t offset);
|
||||
|
||||
/**
|
||||
* @brief Get context data from OCF IO
|
||||
*
|
||||
* @param[in] io OCF IO to get data
|
||||
*
|
||||
* @return Data vector from IO
|
||||
*/
|
||||
ctx_data_t *(*get_data)(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Increase reference counter in OCF IO
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
*/
|
||||
void (*get)(struct ocf_io *io);
|
||||
|
||||
/**
|
||||
* @brief Decrease reference counter in OCF IO
|
||||
*
|
||||
* @note If IO don't have any reference - deallocate it
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
*/
|
||||
void (*put)(struct ocf_io *io);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Configure OCF IO
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
* @param[in] addr OCF IO destination address
|
||||
* @param[in] bytes OCF IO size in bytes
|
||||
* @param[in] dir OCF IO direction
|
||||
* @param[in] class OCF IO destination class
|
||||
* @param[in] flags OCF IO flags
|
||||
*/
|
||||
static inline void ocf_io_configure(struct ocf_io *io, uint64_t addr,
|
||||
uint32_t bytes, uint32_t dir, uint32_t class, uint64_t flags)
|
||||
{
|
||||
io->addr = addr;
|
||||
io->bytes = bytes;
|
||||
io->class = class;
|
||||
io->flags = flags;
|
||||
io->dir = dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Increase reference counter in OCF IO
|
||||
*
|
||||
* @note Wrapper for get IO operation
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
*/
|
||||
static inline void ocf_io_get(struct ocf_io *io)
|
||||
{
|
||||
io->ops->get(io);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decrease reference counter in OCF IO
|
||||
*
|
||||
* @note If IO don't have any reference - deallocate it
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
*/
|
||||
static inline void ocf_io_put(struct ocf_io *io)
|
||||
{
|
||||
io->ops->put(io);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set OCF IO completion function
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
* @param[in] context Context for completion function
|
||||
* @param[in] fn Completion function
|
||||
*/
|
||||
static inline void ocf_io_set_cmpl(struct ocf_io *io, void *context,
|
||||
void *context2, ocf_end_io_t fn)
|
||||
{
|
||||
io->priv1 = context;
|
||||
io->priv2 = context2;
|
||||
io->end = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set OCF IO start function
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
* @param[in] fn Start callback function
|
||||
*/
|
||||
static inline void ocf_io_set_start(struct ocf_io *io, ocf_start_io_t fn)
|
||||
{
|
||||
io->start = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set OCF IO handle function
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
* @param[in] fn Handle callback function
|
||||
*/
|
||||
static inline void ocf_io_set_handle(struct ocf_io *io, ocf_handle_io_t fn)
|
||||
{
|
||||
io->handle = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call default completion function
|
||||
*
|
||||
* @note It is helper function for legacy completion functions
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
* @param[in] error Completion status code
|
||||
*/
|
||||
static inline void ocf_io_end_default(struct ocf_io *io, int error)
|
||||
{
|
||||
ocf_end_t end = io->priv2;
|
||||
|
||||
end(io->priv1, error);
|
||||
|
||||
ocf_io_put(io);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set OCF IO default completion function
|
||||
*
|
||||
* @note This type of completion is for legacy completion type
|
||||
*
|
||||
* @param[in] io OCF IO
|
||||
* @param[in] context Context for completion function
|
||||
* @param[in] fn Completion function
|
||||
*/
|
||||
static inline void ocf_io_set_default_cmpl(struct ocf_io *io, void *context,
|
||||
ocf_end_t fn)
|
||||
{
|
||||
io->priv1 = context;
|
||||
io->priv2 = fn;
|
||||
io->end = ocf_io_end_default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set up data vector in OCF IO
|
||||
*
|
||||
* @note Wrapper for set up data vector function
|
||||
*
|
||||
* @param[in] io OCF IO to set up
|
||||
* @param[in] data Source data vector
|
||||
* @param[in] offset Data offset in source data vector
|
||||
*
|
||||
* @retval 0 Data set up successfully
|
||||
* @retval Non-zero Data set up failure
|
||||
*/
|
||||
static inline int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data,
|
||||
uint32_t offset)
|
||||
{
|
||||
return io->ops->set_data(io, data, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get data vector from OCF IO
|
||||
*
|
||||
* @note Wrapper for get data vector function
|
||||
*
|
||||
* @param[in] io OCF IO to get data
|
||||
*
|
||||
* @return Data vector from IO
|
||||
*/
|
||||
static inline ctx_data_t *ocf_io_get_data(struct ocf_io *io)
|
||||
{
|
||||
return io->ops->get_data(io);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set queue id to which IO should be submitted
|
||||
*
|
||||
* @param[in] io OCF IO to set up
|
||||
* @param[in] queue IO queue id
|
||||
*/
|
||||
static inline void ocf_io_set_queue(struct ocf_io *io, uint32_t queue)
|
||||
{
|
||||
io->io_queue = queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle IO in cache engine
|
||||
*
|
||||
* @param[in] io OCF IO to be handled
|
||||
* @param[in] opaque OCF opaque
|
||||
*/
|
||||
void ocf_io_handle(struct ocf_io *io, void *opaque);
|
||||
|
||||
#endif /* __OCF_IO_H__ */
|
||||
109
inc/ocf_io_class.h
Normal file
109
inc/ocf_io_class.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief IO class API
|
||||
*
|
||||
* File contains structures and methods for handling IO Class
|
||||
* differentiation features
|
||||
*/
|
||||
|
||||
#ifndef __OCF_IO_CLASS_H__
|
||||
#define __OCF_IO_CLASS_H__
|
||||
|
||||
/**
|
||||
* @brief OCF IO class information
|
||||
*/
|
||||
struct ocf_io_class_info {
|
||||
char name[OCF_IO_CLASS_NAME_MAX];
|
||||
/*!< The name of the IO class */
|
||||
|
||||
ocf_cache_mode_t cache_mode;
|
||||
/*!< Cache mode of the IO class */
|
||||
|
||||
int16_t priority;
|
||||
/*!< IO class priority */
|
||||
|
||||
uint32_t curr_size;
|
||||
/*!< Current size of the IO class - number of cache lines which
|
||||
* were assigned into this IO class
|
||||
*/
|
||||
|
||||
uint32_t min_size;
|
||||
/*!< Minimum number of cache lines that were guaranteed
|
||||
* for specified IO class. If current size reach minimum size
|
||||
* that no more eviction takes place
|
||||
*/
|
||||
|
||||
uint32_t max_size;
|
||||
/*!< Maximum number of cache lines that might be assigned into
|
||||
* this IO class. If current size reach maximum size no more
|
||||
* allocation for this IO class takes place
|
||||
*/
|
||||
|
||||
uint8_t eviction_policy_type;
|
||||
/*!< The type of eviction policy for given IO class */
|
||||
|
||||
ocf_cleaning_t cleaning_policy_type;
|
||||
/*!< The type of cleaning policy for given IO class */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief retrieve io class info
|
||||
*
|
||||
* function meant to retrieve information pertaining to particular IO class,
|
||||
* specifically to fill ocf_io_class_info structure based on input parameters.
|
||||
*
|
||||
* @param[in] cache cache id, to which specified request pertains.
|
||||
* @param[in] io_class id of an io class which shall be retreived.
|
||||
* @param[out] info io class info structure to be filled as a
|
||||
* result of this function call.
|
||||
*
|
||||
* @return function returns 0 upon successful completion; appropriate error
|
||||
* code is returned otherwise
|
||||
*/
|
||||
int ocf_io_class_get_info(ocf_cache_t cache, uint32_t io_class,
|
||||
struct ocf_io_class_info *info);
|
||||
|
||||
/**
|
||||
* @brief helper function for ocf_io_class_visit
|
||||
*
|
||||
* This function is called back from ocf_io_class_visit for each valid
|
||||
* configured io class; henceforth all parameters are input parameters,
|
||||
* no exceptions. It is usable to enumerate all the io classes.
|
||||
*
|
||||
* @param[in] cache cache id of cache for which data is being retrieved
|
||||
* @param[in] io_class_id id of an io class for which callback herein
|
||||
* is invoked.
|
||||
* @param[in] cntx a context pointer passed herein from within
|
||||
* ocf_io_class_visit down to this callback.
|
||||
*
|
||||
* @return 0 upon success; Nonzero upon failure (when nonzero is returned,
|
||||
* this callback won't be invoked for any more io classes)
|
||||
*/
|
||||
typedef int (*ocf_io_class_visitor_t)(ocf_cache_t cache,
|
||||
uint32_t io_class_id, void *cntx);
|
||||
|
||||
/**
|
||||
* @brief enumerate all of the available IO classes.
|
||||
*
|
||||
* This function allows enumeration and retrieval of all io class id's that
|
||||
* are valid for given cache id via visiting all those with callback function
|
||||
* that is supplied by caller.
|
||||
*
|
||||
* @param[in] cache cache id to which given call pertains
|
||||
* @param[in] visitor a callback function that will be issued for each and every
|
||||
* IO class that is configured and valid within given cache instance
|
||||
* @param[in] cntx a context variable - structure that shall be passed to a
|
||||
* callback function for every call
|
||||
*
|
||||
* @return 0 upon successful completion of the function; otherwise nonzero result
|
||||
* shall be returned
|
||||
*/
|
||||
int ocf_io_class_visit(ocf_cache_t cache, ocf_io_class_visitor_t visitor,
|
||||
void *cntx);
|
||||
|
||||
#endif /* __OCF_IO_CLASS_H__ */
|
||||
41
inc/ocf_logger.h
Normal file
41
inc/ocf_logger.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef __OCF_LOGGER_H__
|
||||
#define __OCF_LOGGER_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Logger API
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/**
|
||||
* @brief Verbosity levels of context log
|
||||
*/
|
||||
typedef enum {
|
||||
log_emerg,
|
||||
log_alert,
|
||||
log_crit,
|
||||
log_err,
|
||||
log_warn,
|
||||
log_notice,
|
||||
log_info,
|
||||
log_debug,
|
||||
} ocf_logger_lvl_t;
|
||||
|
||||
struct ocf_logger {
|
||||
int (*open)(const struct ocf_logger *logger);
|
||||
void (*close)(const struct ocf_logger *logger);
|
||||
int (*printf)(const struct ocf_logger *logger, ocf_logger_lvl_t lvl,
|
||||
const char *fmt, va_list args);
|
||||
int (*printf_rl)(const char *func_name);
|
||||
int (*dump_stack)(const struct ocf_logger *logger);
|
||||
|
||||
void *priv;
|
||||
};
|
||||
|
||||
#endif /* __OCF_LOGGER_H__ */
|
||||
99
inc/ocf_metadata.h
Normal file
99
inc/ocf_metadata.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef __OCF_METADATA_H__
|
||||
#define __OCF_METADATA_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF metadata helper function
|
||||
*
|
||||
* Those functions can be used by data object implementation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Atomic metadata for extended sector
|
||||
*
|
||||
* @warning The size of this structure has to be equal 8 bytes
|
||||
*/
|
||||
struct ocf_atomic_metadata {
|
||||
/** Core line of core (in cache line size unit) which are cached */
|
||||
uint64_t core_line : 46;
|
||||
|
||||
/** Core sequence number to which this line belongs to*/
|
||||
uint32_t core_seq_no : 16;
|
||||
|
||||
/** Set bit indicates that given sector is valid (is cached) */
|
||||
uint32_t valid : 1;
|
||||
|
||||
/** Set bit indicates that sector i dirty */
|
||||
uint32_t dirty : 1;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define OCF_ATOMIC_METADATA_SIZE sizeof(struct ocf_atomic_metadata)
|
||||
|
||||
/**
|
||||
* @brief Get metadata entry (cache mapping) for specified sector of cache
|
||||
* device
|
||||
*
|
||||
* Metadata has sector granularity. It might be used by data object which
|
||||
* supports atomic writes - (write of data and metadata in one buffer)
|
||||
*
|
||||
* @param[in] cache OCF cache instance
|
||||
* @param[in] addr Sector address in bytes
|
||||
* @param[out] entry Metadata entry
|
||||
*
|
||||
* @retval 0 Metadata retrieved successfully
|
||||
* @retval Non-zero Error
|
||||
*/
|
||||
int ocf_metadata_get_atomic_entry(ocf_cache_t cache, uint64_t addr,
|
||||
struct ocf_atomic_metadata *entry);
|
||||
|
||||
/**
|
||||
* @brief Probe cache device
|
||||
*
|
||||
* @param[in] ctx handle to object designating ocf context
|
||||
* @param[in] cache_obj Cache data object
|
||||
* @param[out] clean_shutdown Cache was graceful stopped
|
||||
* @param[out] cache_dirty Cache is dirty
|
||||
*
|
||||
* @retval 0 Probe successfully performed
|
||||
* @retval -ENODATA Cache has not been detected
|
||||
* @retval Non-zero ERROR
|
||||
*/
|
||||
int ocf_metadata_probe(ocf_ctx_t ctx, ocf_data_obj_t cache_obj,
|
||||
bool *clean_shutdown, bool *cache_dirty);
|
||||
|
||||
/**
|
||||
* @brief Check if sectors in cache line before given address are invalid
|
||||
*
|
||||
* It might be used by data object which supports
|
||||
* atomic writes - (write of data and metadata in one buffer)
|
||||
*
|
||||
* @param[in] cache OCF cache instance
|
||||
* @param[in] addr Sector address in bytes
|
||||
*
|
||||
* @retval 0 Not all sectors before given address are invalid
|
||||
* @retval Non-zero Number of sectors before given address
|
||||
*/
|
||||
int ocf_metadata_check_invalid_before(ocf_cache_t cache, uint64_t addr);
|
||||
|
||||
/**
|
||||
* @brief Check if sectors in cache line after given end address are invalid
|
||||
*
|
||||
* It might be used by data object which supports
|
||||
* atomic writes - (write of data and metadata in one buffer)
|
||||
*
|
||||
* @param[in] cache OCF cache instance
|
||||
* @param[in] addr Sector address in bytes
|
||||
* @param[in] bytes IO size in bytes
|
||||
*
|
||||
* @retval 0 Not all sectors after given end address are invalid
|
||||
* @retval Non-zero Number of sectors after given end address
|
||||
*/
|
||||
int ocf_metadata_check_invalid_after(ocf_cache_t cache, uint64_t addr,
|
||||
uint32_t bytes);
|
||||
|
||||
#endif /* __OCF_METADATA_H__ */
|
||||
50
inc/ocf_metadata_updater.h
Normal file
50
inc/ocf_metadata_updater.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef __OCF_METADATA_UPDATER_H__
|
||||
#define __OCF_METADATA_UPDATER_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF metadata updater API
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Run metadata updater
|
||||
*
|
||||
* @param[in] mu Metadata updater instance to run
|
||||
*
|
||||
* @retval Hint if there is need to rerun without waiting.
|
||||
*/
|
||||
uint32_t ocf_metadata_updater_run(ocf_metadata_updater_t mu);
|
||||
|
||||
/**
|
||||
* @brief Set metadata updater private data
|
||||
*
|
||||
* @param[in] c Metadata updater handle
|
||||
* @param[in] priv Private data
|
||||
*/
|
||||
void ocf_metadata_updater_set_priv(ocf_metadata_updater_t mu, void *priv);
|
||||
|
||||
/**
|
||||
* @brief Get metadata updater private data
|
||||
*
|
||||
* @param[in] c Metadata updater handle
|
||||
*
|
||||
* @retval Metadata updater private data
|
||||
*/
|
||||
void *ocf_metadata_updater_get_priv(ocf_metadata_updater_t mu);
|
||||
|
||||
/**
|
||||
* @brief Get cache instance to which metadata updater belongs
|
||||
*
|
||||
* @param[in] c Metadata updater handle
|
||||
*
|
||||
* @retval Cache instance
|
||||
*/
|
||||
ocf_cache_t ocf_metadata_updater_get_cache(ocf_metadata_updater_t mu);
|
||||
|
||||
#endif /* __OCF_METADATA_UPDATER_H__ */
|
||||
813
inc/ocf_mngt.h
Normal file
813
inc/ocf_mngt.h
Normal file
@@ -0,0 +1,813 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef __OCF_MNGT_H__
|
||||
#define __OCF_MNGT_H__
|
||||
|
||||
#include "ocf_types.h"
|
||||
#include "ocf_cache.h"
|
||||
#include "ocf_core.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF management operations definitions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Core start configuration
|
||||
*/
|
||||
struct ocf_mngt_core_config {
|
||||
/**
|
||||
* @brief OCF core data object UUID
|
||||
*/
|
||||
struct ocf_data_obj_uuid uuid;
|
||||
|
||||
/**
|
||||
* @brief OCF core data object type
|
||||
*/
|
||||
uint8_t data_obj_type;
|
||||
|
||||
/**
|
||||
* @brief OCF core ID number
|
||||
*/
|
||||
ocf_core_id_t core_id;
|
||||
|
||||
/**
|
||||
* @brief OCF core name. In case of being NULL, core id is stringified
|
||||
* to core name
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* @brief OCF core name size
|
||||
*/
|
||||
size_t name_size;
|
||||
|
||||
/**
|
||||
* @brief OCF cache ID number
|
||||
*/
|
||||
ocf_cache_id_t cache_id;
|
||||
|
||||
/**
|
||||
* @brief Add core to pool if cache isn't present or add core to
|
||||
* earlier loaded cache
|
||||
*/
|
||||
bool try_add;
|
||||
|
||||
uint32_t seq_cutoff_threshold;
|
||||
/*!< Sequential cutoff threshold (in bytes) */
|
||||
|
||||
struct {
|
||||
void *data;
|
||||
size_t size;
|
||||
} user_metadata;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get number of OCF caches
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
*
|
||||
* @retval Number of caches in given OCF instance
|
||||
*/
|
||||
uint32_t ocf_mngt_cache_get_count(ocf_ctx_t ctx);
|
||||
|
||||
/* Cache instances getters */
|
||||
|
||||
/**
|
||||
* @brief Get OCF cache
|
||||
*
|
||||
* @note This function on success also increasing reference counter in given
|
||||
* cache
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] id OCF cache ID
|
||||
* @param[out] cache OCF cache handle
|
||||
*
|
||||
* @retval 0 Get cache successfully
|
||||
* @retval -OCF_ERR_INV_CACHE_ID Cache ID out of range
|
||||
* @retval -OCF_ERR_CACHE_NOT_EXIST Cache with given ID is not exist
|
||||
*/
|
||||
int ocf_mngt_cache_get(ocf_ctx_t ctx, ocf_cache_id_t id, ocf_cache_t *cache);
|
||||
|
||||
/**
|
||||
* @brief Decrease reference counter in cache
|
||||
*
|
||||
* @note If cache don't have any reference - deallocate it
|
||||
*
|
||||
* @param[in] cache Handle to cache
|
||||
*/
|
||||
void ocf_mngt_cache_put(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Lock cache for management oparations (write lock, exclusive)
|
||||
*
|
||||
* @param[in] cache Handle to cache
|
||||
*
|
||||
* @retval 0 Cache successfully locked
|
||||
* @retval -OCF_ERR_CACHE_NOT_EXIST Can not lock cache - cache is already
|
||||
* stopping
|
||||
* @retval -OCF_ERR_CACHE_IN_USE Can not lock cache - cache is in use
|
||||
* @retval -OCF_ERR_INTR Wait operation interrupted
|
||||
*/
|
||||
int ocf_mngt_cache_lock(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Lock cache for read - assures cache config does not change while
|
||||
* lock is being held, while allowing other users to acquire
|
||||
* read lock in parallel.
|
||||
*
|
||||
* @param[in] cache Handle to cache
|
||||
*
|
||||
* @retval 0 Cache successfully locked
|
||||
* @retval -OCF_ERR_CACHE_NOT_EXIST Can not lock cache - cache is already
|
||||
* stopping
|
||||
* @retval -OCF_ERR_CACHE_IN_USE Can not lock cache - cache is in use
|
||||
* @retval -OCF_ERR_INTR Wait operation interrupted
|
||||
*/
|
||||
int ocf_mngt_cache_read_lock(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Write-unlock cache
|
||||
*
|
||||
* @param[in] cache Handle to cache
|
||||
*/
|
||||
void ocf_mngt_cache_unlock(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Read-unlock cache
|
||||
*
|
||||
* @param[in] cache Handle to cache
|
||||
*/
|
||||
void ocf_mngt_cache_read_unlock(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Cache visitor function
|
||||
*
|
||||
* @param[in] cache Handle to cache
|
||||
* @param[in] cntx Visitor function context
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Error
|
||||
*/
|
||||
typedef int (*ocf_mngt_cache_visitor_t)(ocf_cache_t cache, void *cntx);
|
||||
|
||||
/**
|
||||
* @brief Loop for each cache
|
||||
*
|
||||
* @note Visitor function is called for each cache
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] visitor OCF cache visitor function
|
||||
* @param[in] cntx Context for cache visitor function
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Error
|
||||
*/
|
||||
int ocf_mngt_cache_visit(ocf_ctx_t ctx, ocf_mngt_cache_visitor_t visitor,
|
||||
void *cntx);
|
||||
|
||||
/**
|
||||
* @brief Loop for each cache reverse
|
||||
*
|
||||
* @note Visitor function is called for each cache
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] visitor OCF cache visitor function
|
||||
* @param[in] cntx Context for cache visitor function
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Error
|
||||
*/
|
||||
int ocf_mngt_cache_visit_reverse(ocf_ctx_t ctx, ocf_mngt_cache_visitor_t visitor,
|
||||
void *cntx);
|
||||
|
||||
/**
|
||||
* @brief Cache probe status
|
||||
*/
|
||||
struct ocf_mngt_cache_probe_status {
|
||||
/**
|
||||
* @brief Gracefully shutdown for cache detected
|
||||
*/
|
||||
bool clean_shutdown;
|
||||
|
||||
/**
|
||||
* @brief Cache is dirty and requires flushing
|
||||
*/
|
||||
bool cache_dirty;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Cache start configuration
|
||||
*/
|
||||
struct ocf_mngt_cache_config {
|
||||
/**
|
||||
* @brief Cache ID. In case of setting this field to invalid cache
|
||||
* id first available cache ID will be set
|
||||
*/
|
||||
ocf_cache_id_t id;
|
||||
|
||||
/**
|
||||
* @brief Cache name. In case of being NULL, cache id is stringified to
|
||||
* cache name
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* @brief Size of cache name
|
||||
*/
|
||||
size_t name_size;
|
||||
|
||||
/**
|
||||
* @brief Cache mode
|
||||
*/
|
||||
ocf_cache_mode_t cache_mode;
|
||||
|
||||
/**
|
||||
* @brief Eviction policy type
|
||||
*/
|
||||
ocf_eviction_t eviction_policy;
|
||||
|
||||
/**
|
||||
* @brief Cache line size
|
||||
*/
|
||||
ocf_cache_line_size_t cache_line_size;
|
||||
|
||||
/**
|
||||
* @brief Metadata layout (stripping/sequential)
|
||||
*/
|
||||
ocf_metadata_layout_t metadata_layout;
|
||||
|
||||
bool metadata_volatile;
|
||||
|
||||
/**
|
||||
* @brief Backfill configuration
|
||||
*/
|
||||
struct {
|
||||
uint32_t max_queue_size;
|
||||
uint32_t queue_unblock_size;
|
||||
} backfill;
|
||||
|
||||
/**
|
||||
* @brief Number of I/O queues to be created
|
||||
*/
|
||||
uint32_t io_queues;
|
||||
|
||||
/**
|
||||
* @brief Start cache and keep it locked
|
||||
*
|
||||
* @note In this case caller is able to perform additional activities
|
||||
* and then shall unlock cache
|
||||
*/
|
||||
bool locked;
|
||||
|
||||
/**
|
||||
* @brief Use pass-through mode for I/O requests unaligned to 4KiB
|
||||
*/
|
||||
bool pt_unaligned_io;
|
||||
|
||||
/**
|
||||
* @brief If set, try to submit all I/O in fast path.
|
||||
*/
|
||||
bool use_submit_io_fast;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Cache attach configuration
|
||||
*/
|
||||
struct ocf_mngt_cache_device_config {
|
||||
/**
|
||||
* @brief Cache data object UUID
|
||||
*/
|
||||
struct ocf_data_obj_uuid uuid;
|
||||
|
||||
/**
|
||||
* @brief Cache data object type
|
||||
*/
|
||||
uint8_t data_obj_type;
|
||||
|
||||
/**
|
||||
* @brief Cache line size
|
||||
*/
|
||||
ocf_cache_line_size_t cache_line_size;
|
||||
|
||||
/**
|
||||
* @brief Ignore warnings and start cache
|
||||
*
|
||||
* @note It will force starting cache despite the:
|
||||
* - overwrite dirty shutdown of previous cache
|
||||
* - ignore cache with dirty shutdown and reinitialize cache
|
||||
*/
|
||||
bool force;
|
||||
|
||||
/**
|
||||
* @brief Minimum free RAM required to start cache. Set during
|
||||
* cache start procedure
|
||||
*/
|
||||
uint64_t min_free_ram;
|
||||
|
||||
/**
|
||||
* @brief If set, cache features (like discard) are tested
|
||||
* before starting cache
|
||||
*/
|
||||
bool perform_test;
|
||||
|
||||
/**
|
||||
* @brief If set, cache device will be discarded on cache start
|
||||
*/
|
||||
bool discard_on_start;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Start cache instance
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[out] cache Cache handle
|
||||
* @param[in] cfg Starting cache configuration
|
||||
*
|
||||
* @retval 0 Cache started successfully
|
||||
* @retval Non-zero Error occurred and starting cache failed
|
||||
*/
|
||||
int ocf_mngt_cache_start(ocf_ctx_t ctx, ocf_cache_t *cache,
|
||||
struct ocf_mngt_cache_config *cfg);
|
||||
|
||||
/**
|
||||
* @brief Stop cache instance
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
*
|
||||
* @retval 0 Cache successfully stopped
|
||||
* @retval Non-zero Error occurred during stopping cache
|
||||
*/
|
||||
int ocf_mngt_cache_stop(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Stop cache instance without acquiring cache lock - caller is
|
||||
* required to hold cache write lock when calling this
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
*
|
||||
* @retval 0 Cache successfully stopped
|
||||
* @retval Non-zero Error occurred during stopping cache
|
||||
*/
|
||||
int ocf_mngt_cache_stop_nolock(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Attach caching device to cache instance
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] device_cfg Caching device configuration
|
||||
*
|
||||
* @retval 0 Cache cache successfully attached
|
||||
* @retval Non-zero Error occurred during attaching cache
|
||||
*/
|
||||
int ocf_mngt_cache_attach(ocf_cache_t cache,
|
||||
struct ocf_mngt_cache_device_config *device_cfg);
|
||||
|
||||
/**
|
||||
* @brief Attach caching device to cache instance without acquiring cache lock
|
||||
* - caller is required to hold cache write lock when calling this
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] device_cfg Caching device configuration
|
||||
*
|
||||
* @retval 0 Cache cache successfully attached
|
||||
* @retval Non-zero Error occurred during attaching cache
|
||||
*/
|
||||
int ocf_mngt_cache_attach_nolock(ocf_cache_t cache,
|
||||
struct ocf_mngt_cache_device_config *device_cfg);
|
||||
|
||||
/**
|
||||
* @brief Detach caching cache
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
*
|
||||
* @retval 0 Cache cache successfully detached
|
||||
* @retval Non-zero Error occurred during stopping cache
|
||||
*/
|
||||
int ocf_mngt_cache_detach(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Load cache instance
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] cfg Cache configuration
|
||||
* @param[in] device_cfg Caching device configuration
|
||||
*
|
||||
* @retval 0 Cache successfully loaded
|
||||
* @retval Non-zero Error occurred during loading cache
|
||||
*/
|
||||
int ocf_mngt_cache_load(ocf_ctx_t ctx, ocf_cache_t *cache,
|
||||
struct ocf_mngt_cache_config *cfg,
|
||||
struct ocf_mngt_cache_device_config *device_cfg);
|
||||
|
||||
/* Adding and removing cores */
|
||||
|
||||
/**
|
||||
* @brief Add core to cache instance
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] core Core object handle
|
||||
* @param[in] cfg Core configuration
|
||||
*
|
||||
* @retval 0 Core successfully added core to cache
|
||||
* @retval Non-zero Error occurred and adding core failed
|
||||
*/
|
||||
int ocf_mngt_cache_add_core(ocf_cache_t cache, ocf_core_t *core,
|
||||
struct ocf_mngt_core_config *cfg);
|
||||
|
||||
/**
|
||||
* @brief Add core to cache instance without acquiring cache lock - caller is
|
||||
required to hold cache write lock when calling this
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] core Core object handle
|
||||
* @param[in] cfg Core configuration
|
||||
*
|
||||
* @retval 0 Core successfully added core to cache
|
||||
* @retval Non-zero Error occurred and adding core failed
|
||||
*/
|
||||
int ocf_mngt_cache_add_core_nolock(ocf_cache_t cache, ocf_core_t *core,
|
||||
struct ocf_mngt_core_config *cfg);
|
||||
|
||||
/**
|
||||
* @brief Remove core from cache instance
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] core_id Core ID
|
||||
* @param[in] detach only detach core without removing it from cache metadata
|
||||
*
|
||||
* @retval 0 Core successfully removed core from cache
|
||||
* @retval Non-zero Error occurred and removing core failed
|
||||
*/
|
||||
int ocf_mngt_cache_remove_core(ocf_cache_t cache, ocf_core_id_t core_id,
|
||||
bool detach);
|
||||
|
||||
/**
|
||||
* @brief Remove core from cache instance without acquiring cache lock - caller
|
||||
* is required to hold cache write lock when calling this
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] core_id Core ID
|
||||
* @param[in] detach only detach core without removing it from cache metadata
|
||||
*
|
||||
* @retval 0 Core successfully removed core from cache
|
||||
* @retval Non-zero Error occurred and removing core failed
|
||||
*/
|
||||
int ocf_mngt_cache_remove_core_nolock(ocf_cache_t cache, ocf_core_id_t core_id,
|
||||
bool detach);
|
||||
|
||||
/* Flush operations */
|
||||
|
||||
/**
|
||||
* @brief Flush data from given cache
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] interruption Allow for interruption
|
||||
*
|
||||
* @retval 0 Successfully flushed given cache
|
||||
* @retval Non-zero Error occurred and flushing cache failed
|
||||
*/
|
||||
int ocf_mngt_cache_flush(ocf_cache_t cache, bool interruption);
|
||||
|
||||
/**
|
||||
* @brief Flush data from given cache without acquiring cache lock - caller is
|
||||
* required to hold cache write OR read lock when calling this
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] interruption Allow for interruption
|
||||
*
|
||||
* @retval 0 Successfully flushed given cache
|
||||
* @retval Non-zero Error occurred and flushing cache failed
|
||||
*/
|
||||
int ocf_mngt_cache_flush_nolock(ocf_cache_t cache, bool interruption);
|
||||
|
||||
/**
|
||||
* @brief Flush data to given core
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] id Core ID
|
||||
* @param[in] interruption Allow for interruption
|
||||
*
|
||||
* @retval 0 Successfully flushed data to given core
|
||||
* @retval Non-zero Error occurred and flushing data to core failed
|
||||
*/
|
||||
int ocf_mngt_core_flush(ocf_cache_t cache, ocf_core_id_t id, bool interruption);
|
||||
|
||||
/**
|
||||
* @brief Flush data to given core without acquiring cache lock - caller is
|
||||
* required to hold cache write OR read lock when calling this
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] id Core ID
|
||||
* @param[in] interruption Allow for interruption
|
||||
*
|
||||
* @retval 0 Successfully flushed data to given core
|
||||
* @retval Non-zero Error occurred and flushing data to core failed
|
||||
*/
|
||||
int ocf_mngt_core_flush_nolock(ocf_cache_t cache, ocf_core_id_t id,
|
||||
bool interruption);
|
||||
/**
|
||||
* @brief Interrupt existing flushing of cache or cache
|
||||
*
|
||||
* @param[in] cache Cache instance
|
||||
*
|
||||
* @retval 0 Operation success
|
||||
* @retval Non-zero Operation failure
|
||||
*/
|
||||
int ocf_mngt_cache_flush_interrupt(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Purge data to given core
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] id Core ID
|
||||
* @param[in] interruption Allow for interruption
|
||||
*
|
||||
* @retval 0 Successfully purged data to given core
|
||||
* @retval Non-zero Error occurred and purging data to core failed
|
||||
*/
|
||||
int ocf_mngt_core_purge(ocf_cache_t cache, ocf_core_id_t id, bool interruption);
|
||||
/**
|
||||
* @brief Purge data from given cache
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] interruption Allow for interruption
|
||||
*
|
||||
* @retval 0 Successfully purged given cache
|
||||
* @retval Non-zero Error occurred and purging cache failed
|
||||
*/
|
||||
int ocf_mngt_cache_purge(ocf_cache_t cache, bool interruption);
|
||||
|
||||
/**
|
||||
* @brief Set cleaning policy in given cache
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] type Cleainig policy type
|
||||
*
|
||||
* @retval 0 Policy has been set successfully
|
||||
* @retval Non-zero Error occurred and policy has not been set
|
||||
*/
|
||||
int ocf_mngt_cache_cleaning_set_policy(ocf_cache_t cache, ocf_cleaning_t type);
|
||||
|
||||
/**
|
||||
* @brief Get current cleaning policy from given cache
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[out] type Variable to store current cleaning policy type
|
||||
*
|
||||
* @retval 0 Policy has been get successfully
|
||||
* @retval Non-zero Error occurred and policy has not been get
|
||||
*/
|
||||
int ocf_mngt_cache_cleaning_get_policy(ocf_cache_t cache, ocf_cleaning_t *type);
|
||||
|
||||
/**
|
||||
* @brief Set cleaning parameter in given cache
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] param_id Cleaning policy parameter id
|
||||
* @param[in] param_value Cleaning policy parameter value
|
||||
*
|
||||
* @retval 0 Parameter has been set successfully
|
||||
* @retval Non-zero Error occurred and parameter has not been set
|
||||
*/
|
||||
int ocf_mngt_cache_cleaning_set_param(ocf_cache_t cache, ocf_cleaning_t type,
|
||||
uint32_t param_id, uint32_t param_value);
|
||||
|
||||
/**
|
||||
* @brief Get cleaning parameter from given cache
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] param_id Cleaning policy parameter id
|
||||
* @param[in] param_value Variable to store parameter value
|
||||
*
|
||||
* @retval 0 Parameter has been get successfully
|
||||
* @retval Non-zero Error occurred and parameter has not been get
|
||||
*/
|
||||
int ocf_mngt_cache_cleaning_get_param(ocf_cache_t cache,ocf_cleaning_t type,
|
||||
uint32_t param_id, uint32_t *param_value);
|
||||
|
||||
/**
|
||||
* @brief IO class configuration
|
||||
*/
|
||||
struct ocf_mngt_io_class_config {
|
||||
/**
|
||||
* @brief IO class ID
|
||||
*/
|
||||
uint32_t class_id;
|
||||
|
||||
/**
|
||||
* @brief IO class name
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* @brief IO class eviction priority
|
||||
*/
|
||||
int16_t prio;
|
||||
|
||||
/**
|
||||
* @brief IO class cache mode
|
||||
*/
|
||||
ocf_cache_mode_t cache_mode;
|
||||
|
||||
/**
|
||||
* @brief IO class minimum size
|
||||
*/
|
||||
uint32_t min_size;
|
||||
|
||||
/**
|
||||
* @brief IO class maximum size
|
||||
*/
|
||||
uint32_t max_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Configure IO class in given cache
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] cfg IO class configuration
|
||||
*
|
||||
* @retval 0 Configuration have been set successfully
|
||||
* @retval Non-zero Error occurred and configuration not been set
|
||||
*/
|
||||
int ocf_mngt_io_class_configure(ocf_cache_t cache,
|
||||
const struct ocf_mngt_io_class_config *cfg);
|
||||
|
||||
/**
|
||||
* @brief Set core sequential cutoff threshold
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] core_id Core ID
|
||||
* @param[in] thresh threshold in bytes for sequential cutoff
|
||||
*
|
||||
* @retval 0 Sequential cutoff threshold has been set successfully
|
||||
* @retval Non-zero Error occured and threshold hasn't been updated
|
||||
*/
|
||||
int ocf_mngt_set_seq_cutoff_threshold(ocf_cache_t cache, ocf_core_id_t core_id,
|
||||
uint32_t thresh);
|
||||
|
||||
/**
|
||||
* @brief Set core sequential cutoff policy
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] core_id Core ID
|
||||
* @param[in] policy sequential cutoff policy
|
||||
*
|
||||
* @retval 0 Sequential cutoff policy has been set successfully
|
||||
* @retval Non-zero Error occured and policy hasn't been updated
|
||||
*/
|
||||
int ocf_mngt_set_seq_cutoff_policy(ocf_cache_t cache, ocf_core_id_t core_id,
|
||||
ocf_seq_cutoff_policy policy);
|
||||
|
||||
/**
|
||||
* @brief Get core sequential cutoff threshold
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] core_id Core ID
|
||||
* @param[in] thresh threshold in bytes for sequential cutoff
|
||||
*
|
||||
* @retval 0 Sequential cutoff threshold has been get successfully
|
||||
* @retval Non-zero Error occured
|
||||
*/
|
||||
int ocf_mngt_get_seq_cutoff_threshold(ocf_cache_t cache, ocf_core_id_t core_id,
|
||||
uint32_t *thresh);
|
||||
|
||||
/**
|
||||
* @brief Get core sequential cutoff policy
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] core_id Core ID
|
||||
* @param[in] policy sequential cutoff policy
|
||||
*
|
||||
* @retval 0 Sequential cutoff policy has been get successfully
|
||||
* @retval Non-zero Error occured
|
||||
*/
|
||||
int ocf_mngt_get_seq_cutoff_policy(ocf_cache_t cache, ocf_core_id_t core_id,
|
||||
ocf_seq_cutoff_policy *policy);
|
||||
|
||||
/**
|
||||
* @brief Set cache mode in given cache
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] mode Cache mode to set
|
||||
* @param[in] flush Perform flushing before switch cache mode
|
||||
*
|
||||
* @retval 0 Cache mode have been set successfully
|
||||
* @retval Non-zero Error occurred and cache mode not been set
|
||||
*/
|
||||
int ocf_mngt_cache_set_mode(ocf_cache_t cache, ocf_cache_mode_t mode,
|
||||
uint8_t flush);
|
||||
|
||||
/**
|
||||
* @brief Set cache fallback Pass Through error threshold
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] threshold Value to be set as threshold
|
||||
*
|
||||
* @retval 0 Fallback-PT threshold have been set successfully
|
||||
* @retval Non-zero Error occurred
|
||||
*/
|
||||
int ocf_mngt_cache_set_fallback_pt_error_threshold(ocf_cache_t cache,
|
||||
uint32_t threshold);
|
||||
|
||||
/**
|
||||
* @brief Get cache fallback Pass Through error threshold
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[out] threshold Fallback-PT threshold
|
||||
*
|
||||
* @retval 0 Fallback-PT threshold have been get successfully
|
||||
* @retval Non-zero Error occurred
|
||||
*/
|
||||
int ocf_mngt_cache_get_fallback_pt_error_threshold(ocf_cache_t cache,
|
||||
uint32_t *threshold);
|
||||
|
||||
/**
|
||||
* @brief Reset cache fallback Pass Through error counter
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
*
|
||||
* @retval 0 Threshold have been reset successfully
|
||||
*/
|
||||
int ocf_mngt_cache_reset_fallback_pt_error_counter(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief Initialize core pool
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
*/
|
||||
void ocf_mngt_core_pool_init(ocf_ctx_t ctx);
|
||||
|
||||
/**
|
||||
* @brief Get core pool count
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
*
|
||||
* @retval Number of cores in core pool
|
||||
*/
|
||||
int ocf_mngt_core_pool_get_count(ocf_ctx_t ctx);
|
||||
|
||||
/**
|
||||
* @brief Add core to pool
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] uuid Cache data object UUID
|
||||
* @param[in] type OCF core data object type
|
||||
*
|
||||
* @retval 0 Core added to pool successfully
|
||||
* @retval Non-zero Error occurred and adding core to poll failed
|
||||
*/
|
||||
int ocf_mngt_core_pool_add(ocf_ctx_t ctx, ocf_uuid_t uuid, uint8_t type);
|
||||
|
||||
/**
|
||||
* @brief Add core to pool
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] uuid Cache data object UUID
|
||||
* @param[in] type OCF core data object type
|
||||
*
|
||||
* @retval Handler to object with same UUID
|
||||
* @retval NULL Not found object with that id
|
||||
*/
|
||||
ocf_data_obj_t ocf_mngt_core_pool_lookup(ocf_ctx_t ctx, ocf_uuid_t uuid,
|
||||
ocf_data_obj_type_t type);
|
||||
/**
|
||||
* @brief Iterate over all object in pool and call visitor callback
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] visitor Visitor callback
|
||||
* @param[in] visior_ctx CContext for visitor callback
|
||||
*
|
||||
* @retval Handler to object with same UUID
|
||||
* @retval NULL Not found object with that id
|
||||
*/
|
||||
int ocf_mngt_core_pool_visit(ocf_ctx_t ctx,
|
||||
int (*visitor)(ocf_uuid_t, void *), void *visitor_ctx);
|
||||
|
||||
/**
|
||||
* @brief Remove core from pool
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] obj Core data object
|
||||
*/
|
||||
void ocf_mngt_core_pool_remove(ocf_ctx_t ctx, ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Close and remove core from pool
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
* @param[in] obj Core data object
|
||||
*/
|
||||
void ocf_mngt_core_pool_close_and_remove(ocf_ctx_t ctx, ocf_data_obj_t obj);
|
||||
|
||||
/**
|
||||
* @brief Deinit core pool
|
||||
*
|
||||
* @param[in] ctx OCF context
|
||||
*/
|
||||
void ocf_mngt_core_pool_deinit(ocf_ctx_t ctx);
|
||||
|
||||
#endif /* __OCF_CACHE_H__ */
|
||||
65
inc/ocf_queue.h
Normal file
65
inc/ocf_queue.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef OCF_QUEUE_H_
|
||||
#define OCF_QUEUE_H_
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF queues API
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Run queue processing
|
||||
*
|
||||
* @param[in] q Queue to run
|
||||
*/
|
||||
void ocf_queue_run(ocf_queue_t q);
|
||||
|
||||
/**
|
||||
* @brief Set queue private data
|
||||
*
|
||||
* @param[in] q I/O queue
|
||||
* @param[in] priv Private data
|
||||
*/
|
||||
void ocf_queue_set_priv(ocf_queue_t q, void *priv);
|
||||
|
||||
/**
|
||||
* @brief Get queue private data
|
||||
*
|
||||
* @param[in] q I/O queue
|
||||
*
|
||||
* @retval I/O queue private data
|
||||
*/
|
||||
void *ocf_queue_get_priv(ocf_queue_t q);
|
||||
|
||||
/**
|
||||
* @brief Get number of pending requests in I/O queue
|
||||
*
|
||||
* @param[in] q I/O queue
|
||||
*
|
||||
* @retval Number of pending requests in I/O queue
|
||||
*/
|
||||
uint32_t ocf_queue_pending_io(ocf_queue_t q);
|
||||
|
||||
/**
|
||||
* @brief Get cache instance to which I/O queue belongs
|
||||
*
|
||||
* @param[in] q I/O queue
|
||||
*
|
||||
* @retval Cache instance
|
||||
*/
|
||||
ocf_cache_t ocf_queue_get_cache(ocf_queue_t q);
|
||||
|
||||
/**
|
||||
* @brief Get I/O queue id
|
||||
*
|
||||
* @param[in] q I/O queue
|
||||
*
|
||||
* @retval I/O queue id
|
||||
*/
|
||||
uint32_t ocf_queue_get_id(ocf_queue_t q);
|
||||
|
||||
#endif
|
||||
207
inc/ocf_stats.h
Normal file
207
inc/ocf_stats.h
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF API for getting and reseting statistics
|
||||
*
|
||||
* This file contains routines pertaining to retrieval and
|
||||
* manipulation of OCF IO statistics.
|
||||
*/
|
||||
|
||||
#ifndef __OCF_STATS_H__
|
||||
#define __OCF_STATS_H__
|
||||
|
||||
struct ocf_io;
|
||||
|
||||
/**
|
||||
* @brief OCF requests statistics like hit, miss, etc...
|
||||
*
|
||||
* @note To calculate number of hits request do:
|
||||
* total - (partial_miss + full_miss)
|
||||
*/
|
||||
struct ocf_stats_req {
|
||||
/** Number of partial misses */
|
||||
uint64_t partial_miss;
|
||||
|
||||
/** Number of full misses */
|
||||
uint64_t full_miss;
|
||||
|
||||
/** Total of requests */
|
||||
uint64_t total;
|
||||
|
||||
/** Pass-through requests */
|
||||
uint64_t pass_through;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief OCF error statistics
|
||||
*/
|
||||
struct ocf_stats_error {
|
||||
/** Read errors */
|
||||
uint32_t read;
|
||||
|
||||
/** Write errors */
|
||||
uint32_t write;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief OCF block statistics in bytes
|
||||
*/
|
||||
struct ocf_stats_block {
|
||||
/** Number of blocks read */
|
||||
uint64_t read;
|
||||
|
||||
/** Number of blocks written */
|
||||
uint64_t write;
|
||||
};
|
||||
|
||||
/**
|
||||
* Statistics appropriate for given IO class
|
||||
*/
|
||||
struct ocf_stats_io_class {
|
||||
/** Read requests statistics */
|
||||
struct ocf_stats_req read_reqs;
|
||||
|
||||
/** Writes requests statistics */
|
||||
struct ocf_stats_req write_reqs;
|
||||
|
||||
/** Block requests statistics */
|
||||
struct ocf_stats_block blocks;
|
||||
|
||||
/** Number of cache lines available for given partition */
|
||||
uint64_t free_clines;
|
||||
|
||||
/** Number of cache lines within lru list */
|
||||
uint64_t occupancy_clines;
|
||||
|
||||
/** Number of dirty cache lines assigned to specific partition */
|
||||
uint64_t dirty_clines;
|
||||
};
|
||||
|
||||
#define IO_PACKET_NO 12
|
||||
#define IO_ALIGN_NO 4
|
||||
|
||||
/**
|
||||
* @brief Core debug statistics
|
||||
*/
|
||||
struct ocf_stats_core_debug {
|
||||
/** I/O sizes being read (grouped by packets) */
|
||||
uint64_t read_size[IO_PACKET_NO];
|
||||
|
||||
/** I/O sizes being written (grouped by packets) */
|
||||
uint64_t write_size[IO_PACKET_NO];
|
||||
|
||||
/** I/O alignment for reads */
|
||||
uint64_t read_align[IO_ALIGN_NO];
|
||||
|
||||
/** I/O alignment for writes */
|
||||
uint64_t write_align[IO_ALIGN_NO];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief OCF core statistics
|
||||
*/
|
||||
struct ocf_stats_core {
|
||||
/** Core size in cache line size unit */
|
||||
uint64_t core_size;
|
||||
|
||||
/** Core size in bytes unit */
|
||||
uint64_t core_size_bytes;
|
||||
|
||||
/** Number of cache lines allocated in the cache for this core */
|
||||
uint32_t cache_occupancy;
|
||||
|
||||
/** Number of dirty cache lines allocated in the cache for this core */
|
||||
uint32_t dirty;
|
||||
|
||||
/** Number of block flushed in ongoing flush operation */
|
||||
uint32_t flushed;
|
||||
|
||||
/** How long core is dirty in seconds unit */
|
||||
uint32_t dirty_for;
|
||||
|
||||
/** Read requests statistics */
|
||||
struct ocf_stats_req read_reqs;
|
||||
|
||||
/** Write requests statistics */
|
||||
struct ocf_stats_req write_reqs;
|
||||
|
||||
/** Block requests for cache data object statistics */
|
||||
struct ocf_stats_block cache_obj;
|
||||
|
||||
/** Block requests for core data object statistics */
|
||||
struct ocf_stats_block core_obj;
|
||||
|
||||
/** Block requests submitted by user to this core */
|
||||
struct ocf_stats_block core;
|
||||
|
||||
/** Cache data object error statistics */
|
||||
struct ocf_stats_error cache_errors;
|
||||
|
||||
/** Core data object error statistics */
|
||||
struct ocf_stats_error core_errors;
|
||||
|
||||
/** Debug statistics */
|
||||
struct ocf_stats_core_debug debug_stat;
|
||||
|
||||
/** Sequential cutoff threshold (in bytes) */
|
||||
uint32_t seq_cutoff_threshold;
|
||||
|
||||
/** Sequential cutoff policy */
|
||||
ocf_seq_cutoff_policy seq_cutoff_policy;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialize or reset statistics.
|
||||
*
|
||||
* Initialize or reset counters used for statistics.
|
||||
*
|
||||
* @param[in] cache OCF cache device handle
|
||||
* @param[in] core_id Id of core for which statistics should be initialized.
|
||||
*/
|
||||
int ocf_stats_initialize(ocf_cache_t cache, ocf_core_id_t core_id);
|
||||
|
||||
/**
|
||||
* @brief ocf_io_class_get_stats retrieve cache statistics
|
||||
*
|
||||
* Retrieve buffer of cache statistics for given cache instance.
|
||||
*
|
||||
* @param[in] core core ID to which request pertains
|
||||
* @param[in] io_class IO class, stats of which are requested
|
||||
* @param[out] stats statistics structure that shall be filled as
|
||||
* a result of this function invocation.
|
||||
*
|
||||
* @result zero upon successful completion; error code otherwise
|
||||
*/
|
||||
int ocf_io_class_get_stats(ocf_core_t core, uint32_t io_class,
|
||||
struct ocf_stats_io_class *stats);
|
||||
|
||||
/**
|
||||
* @brief retrieve core stats
|
||||
*
|
||||
* Retrieve ocf per core stats (for all IO classes together)
|
||||
*
|
||||
* @param[in] core core ID to which request pertains
|
||||
* @param[out] stats statistics structure that shall be filled as
|
||||
* a result of this function invocation.
|
||||
*
|
||||
* @result zero upon successful completion; error code otherwise
|
||||
*/
|
||||
int ocf_core_get_stats(ocf_core_t core, struct ocf_stats_core *stats);
|
||||
|
||||
/**
|
||||
* @brief update stats given IO request
|
||||
*
|
||||
* Function meant to update stats for IO request.
|
||||
*
|
||||
* @note This function shall be invoked for eac IO request processed
|
||||
*
|
||||
* @param[in] core to which request pertains
|
||||
* @param[in] io request for which stats are being updated
|
||||
*/
|
||||
void ocf_core_update_stats(ocf_core_t core, struct ocf_io *io);
|
||||
|
||||
#endif /* __OCF_STATS_H__ */
|
||||
190
inc/ocf_stats_builder.h
Normal file
190
inc/ocf_stats_builder.h
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF API for collecting statistics
|
||||
*
|
||||
* This file contains routines pertaining to retrieval and
|
||||
* manipulation of OCF IO statistics.
|
||||
*/
|
||||
|
||||
#ifndef __OCF_STATS_BUILDER_H__
|
||||
#define __OCF_STATS_BUILDER_H__
|
||||
|
||||
/**
|
||||
* Entire row of statistcs
|
||||
*/
|
||||
struct ocf_stat {
|
||||
/** Value */
|
||||
uint64_t value;
|
||||
/** percent x10 */
|
||||
uint64_t percent;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Usage statistics in 4 KiB unit
|
||||
*
|
||||
* An example of presenting statistics:
|
||||
* <pre>
|
||||
* ╔══════════════════╤══════════╤═══════╤═════════════╗
|
||||
* ║ Usage statistics │ Count │ % │ Units ║
|
||||
* ╠══════════════════╪══════════╪═══════╪═════════════╣
|
||||
* ║ Occupancy │ 20 │ 50.0 │ 4KiB blocks ║
|
||||
* ║ Free │ 20 │ 50.0 │ 4KiB blocks ║
|
||||
* ║ Clean │ 15 │ 75.0 │ 4KiB blocks ║
|
||||
* ║ Dirty │ 5 │ 25.0 │ 4KiB blocks ║
|
||||
* ╚══════════════════╧══════════╧═══════╧═════════════╝
|
||||
* </pre>
|
||||
*/
|
||||
struct ocf_stats_usage {
|
||||
struct ocf_stat occupancy;
|
||||
struct ocf_stat free;
|
||||
struct ocf_stat clean;
|
||||
struct ocf_stat dirty;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Requests statistcs
|
||||
*
|
||||
* An example of presenting statistics:
|
||||
* <pre>
|
||||
* ╔══════════════════════╤═══════╤═══════╤══════════╗
|
||||
* ║ Request statistics │ Count │ % │ Units ║
|
||||
* ╠══════════════════════╪═══════╪═══════╪══════════╣
|
||||
* ║ Read hits │ 10 │ 4.5 │ Requests ║
|
||||
* ║ Read partial misses │ 1 │ 0.5 │ Requests ║
|
||||
* ║ Read full misses │ 211 │ 95.0 │ Requests ║
|
||||
* ║ Read total │ 222 │ 100.0 │ Requests ║
|
||||
* ╟──────────────────────┼───────┼───────┼──────────╢
|
||||
* ║ Write hits │ 0 │ 0.0 │ Requests ║
|
||||
* ║ Write partial misses │ 0 │ 0.0 │ Requests ║
|
||||
* ║ Write full misses │ 0 │ 0.0 │ Requests ║
|
||||
* ║ Write total │ 0 │ 0.0 │ Requests ║
|
||||
* ╟──────────────────────┼───────┼───────┼──────────╢
|
||||
* ║ Pass-Through reads │ 0 │ 0.0 │ Requests ║
|
||||
* ║ Pass-Through writes │ 0 │ 0.0 │ Requests ║
|
||||
* ║ Serviced requests │ 222 │ 100.0 │ Requests ║
|
||||
* ╟──────────────────────┼───────┼───────┼──────────╢
|
||||
* ║ Total requests │ 222 │ 100.0 │ Requests ║
|
||||
* ╚══════════════════════╧═══════╧═══════╧══════════╝
|
||||
* </pre>
|
||||
*/
|
||||
struct ocf_stats_requests {
|
||||
struct ocf_stat rd_hits;
|
||||
struct ocf_stat rd_partial_misses;
|
||||
struct ocf_stat rd_full_misses;
|
||||
struct ocf_stat rd_total;
|
||||
struct ocf_stat wr_hits;
|
||||
struct ocf_stat wr_partial_misses;
|
||||
struct ocf_stat wr_full_misses;
|
||||
struct ocf_stat wr_total;
|
||||
struct ocf_stat rd_pt;
|
||||
struct ocf_stat wr_pt;
|
||||
struct ocf_stat serviced;
|
||||
struct ocf_stat total;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Block statistics
|
||||
*
|
||||
* An example of presenting statistics:
|
||||
* <pre>
|
||||
* ╔════════════════════════════════════╤═══════╤═══════╤═════════════╗
|
||||
* ║ Block statistics │ Count │ % │ Units ║
|
||||
* ╠════════════════════════════════════╪═══════╪═══════╪═════════════╣
|
||||
* ║ Reads from core data object(s) │ 426 │ 100.0 │ 4KiB blocks ║
|
||||
* ║ Writes to core data object(s) │ 0 │ 0.0 │ 4KiB blocks ║
|
||||
* ║ Total to/from core data object (s) │ 426 │ 100.0 │ 4KiB blocks ║
|
||||
* ╟────────────────────────────────────┼───────┼───────┼─────────────╢
|
||||
* ║ Reads from cache data object │ 13 │ 3.0 │ 4KiB blocks ║
|
||||
* ║ Writes to cache data object │ 426 │ 97.0 │ 4KiB blocks ║
|
||||
* ║ Total to/from cache data object │ 439 │ 100.0 │ 4KiB blocks ║
|
||||
* ╟────────────────────────────────────┼───────┼───────┼─────────────╢
|
||||
* ║ Reads from core(s) │ 439 │ 100.0 │ 4KiB blocks ║
|
||||
* ║ Writes to core(s) │ 0 │ 0.0 │ 4KiB blocks ║
|
||||
* ║ Total to/from core(s) │ 439 │ 100.0 │ 4KiB blocks ║
|
||||
* ╚════════════════════════════════════╧═══════╧═══════╧═════════════╝
|
||||
* </pre>
|
||||
*/
|
||||
struct ocf_stats_blocks {
|
||||
struct ocf_stat core_obj_rd;
|
||||
struct ocf_stat core_obj_wr;
|
||||
struct ocf_stat core_obj_total;
|
||||
struct ocf_stat cache_obj_rd;
|
||||
struct ocf_stat cache_obj_wr;
|
||||
struct ocf_stat cache_obj_total;
|
||||
struct ocf_stat volume_rd;
|
||||
struct ocf_stat volume_wr;
|
||||
struct ocf_stat volume_total;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Errors statistics
|
||||
*
|
||||
* An example of presenting statistics:
|
||||
* <pre>
|
||||
* ╔════════════════════╤═══════╤═════╤══════════╗
|
||||
* ║ Error statistics │ Count │ % │ Units ║
|
||||
* ╠════════════════════╪═══════╪═════╪══════════╣
|
||||
* ║ Cache read errors │ 0 │ 0.0 │ Requests ║
|
||||
* ║ Cache write errors │ 0 │ 0.0 │ Requests ║
|
||||
* ║ Cache total errors │ 0 │ 0.0 │ Requests ║
|
||||
* ╟────────────────────┼───────┼─────┼──────────╢
|
||||
* ║ Core read errors │ 0 │ 0.0 │ Requests ║
|
||||
* ║ Core write errors │ 0 │ 0.0 │ Requests ║
|
||||
* ║ Core total errors │ 0 │ 0.0 │ Requests ║
|
||||
* ╟────────────────────┼───────┼─────┼──────────╢
|
||||
* ║ Total errors │ 0 │ 0.0 │ Requests ║
|
||||
* ╚════════════════════╧═══════╧═════╧══════════╝
|
||||
* </pre>
|
||||
*/
|
||||
struct ocf_stats_errors {
|
||||
struct ocf_stat core_obj_rd;
|
||||
struct ocf_stat core_obj_wr;
|
||||
struct ocf_stat core_obj_total;
|
||||
struct ocf_stat cache_obj_rd;
|
||||
struct ocf_stat cache_obj_wr;
|
||||
struct ocf_stat cache_obj_total;
|
||||
struct ocf_stat total;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param Collect statistics for given cache
|
||||
*
|
||||
* @param cache Cache instance for each statistics will be collected
|
||||
* @param usage Usage statistics
|
||||
* @param rq Request statistics
|
||||
* @param blocks Blocks statistics
|
||||
* @param errors Errors statistics
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Error
|
||||
*/
|
||||
int ocf_stats_collect_cache(ocf_cache_t cache,
|
||||
struct ocf_stats_usage *usage,
|
||||
struct ocf_stats_requests *rq,
|
||||
struct ocf_stats_blocks *blocks,
|
||||
struct ocf_stats_errors *errors);
|
||||
|
||||
/**
|
||||
* @param Collect statistics for given core
|
||||
*
|
||||
* @param cache Core for each statistics will be collected
|
||||
* @param usage Usage statistics
|
||||
* @param rq Request statistics
|
||||
* @param blocks Blocks statistics
|
||||
* @param errors Errors statistics
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval Non-zero Error
|
||||
*/
|
||||
int ocf_stats_collect_core(ocf_core_t core,
|
||||
struct ocf_stats_usage *usage,
|
||||
struct ocf_stats_requests *rq,
|
||||
struct ocf_stats_blocks *blocks,
|
||||
struct ocf_stats_errors *errors);
|
||||
|
||||
#endif /* __OCF_STATS_BUILDER_H__ */
|
||||
95
inc/ocf_types.h
Normal file
95
inc/ocf_types.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF types
|
||||
*/
|
||||
#ifndef __OCF_TYPES_H_
|
||||
#define __OCF_TYPES_H_
|
||||
|
||||
#include "ocf_env_headers.h"
|
||||
|
||||
/**
|
||||
* @brief cache id type (by default designated as 16 bit unsigned integer)
|
||||
*/
|
||||
typedef uint16_t ocf_cache_id_t;
|
||||
|
||||
/**
|
||||
* @brief cache line type (by default designated as 32 bit unsigned integer)
|
||||
*/
|
||||
typedef uint32_t ocf_cache_line_t;
|
||||
|
||||
/**
|
||||
* @brief core id type (by default designated as 16 bit unsigned integer)
|
||||
*/
|
||||
typedef uint16_t ocf_core_id_t;
|
||||
|
||||
/**
|
||||
* @brief core sequence number type (by default designated as 16 bit unsigned integer)
|
||||
*/
|
||||
typedef uint16_t ocf_seq_no_t;
|
||||
|
||||
/**
|
||||
* @brief partition id type (by default designated as 16 bit unsigned integer)
|
||||
*/
|
||||
typedef uint16_t ocf_part_id_t;
|
||||
|
||||
/**
|
||||
* @brief handle to object designating ocf context
|
||||
*/
|
||||
typedef struct ocf_ctx *ocf_ctx_t;
|
||||
|
||||
struct ocf_cache;
|
||||
/**
|
||||
* @brief handle to object designating ocf cache device
|
||||
*/
|
||||
typedef struct ocf_cache *ocf_cache_t;
|
||||
|
||||
struct ocf_core;
|
||||
/**
|
||||
* @brief handle to object designating ocf core object
|
||||
*/
|
||||
typedef struct ocf_core *ocf_core_t;
|
||||
|
||||
struct ocf_data_obj;
|
||||
/**
|
||||
* @brief handle to object designating ocf data object
|
||||
*/
|
||||
typedef struct ocf_data_obj *ocf_data_obj_t;
|
||||
|
||||
|
||||
struct ocf_data_obj_type;
|
||||
/**
|
||||
* @brief handle to data object type
|
||||
*/
|
||||
typedef const struct ocf_data_obj_type *ocf_data_obj_type_t;
|
||||
|
||||
/**
|
||||
* @brief handle to data object uuid
|
||||
*/
|
||||
typedef struct ocf_data_obj_uuid *ocf_uuid_t;
|
||||
|
||||
/**
|
||||
* @brief handle to object designating ocf context object
|
||||
*/
|
||||
typedef void ctx_data_t;
|
||||
|
||||
/**
|
||||
* @brief handle to I/O queue
|
||||
*/
|
||||
typedef struct ocf_queue *ocf_queue_t;
|
||||
|
||||
/**
|
||||
* @brief handle to cleaner
|
||||
*/
|
||||
typedef struct ocf_cleaner *ocf_cleaner_t;
|
||||
|
||||
/**
|
||||
* @brief handle to metadata_updater
|
||||
*/
|
||||
typedef struct ocf_metadata_updater *ocf_metadata_updater_t;
|
||||
|
||||
#endif
|
||||
74
inc/ocf_utilities.h
Normal file
74
inc/ocf_utilities.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __OCF_UTILITIES_H__
|
||||
#define __OCF_UTILITIES_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief OCF memory pool reference
|
||||
*/
|
||||
|
||||
struct ocf_mpool;
|
||||
|
||||
/**
|
||||
* @brief Create OCF memory pool
|
||||
*
|
||||
* @param cache OCF cache instance
|
||||
* @param size Size of particular item
|
||||
* @param hdr_size Header size before array of items
|
||||
* @param flags Allocation flags
|
||||
* @param mpool_max Maximal allocator size (power of two)
|
||||
* @param fmt_name Format name of allocator
|
||||
* @param ... Format parameters
|
||||
*
|
||||
* @return OCF memory pool reference
|
||||
*/
|
||||
struct ocf_mpool *ocf_mpool_create(struct ocf_cache *cache,
|
||||
uint32_t hdr_size, uint32_t size, int flags, int mpool_max,
|
||||
const char *name_perfix);
|
||||
|
||||
/**
|
||||
* @brief Destroy existing memory pool
|
||||
*
|
||||
* @param mpool memory pool
|
||||
*/
|
||||
void ocf_mpool_destroy(struct ocf_mpool *mpool);
|
||||
|
||||
/**
|
||||
* @brief Allocate new items of memory pool
|
||||
*
|
||||
* @note Allocation based on ATOMIC memory pool and this function can be called
|
||||
* when IRQ disable
|
||||
*
|
||||
* @param mpool OCF memory pool reference
|
||||
* @param count Count of elements to be allocated
|
||||
*
|
||||
* @return Pointer to the new items
|
||||
*/
|
||||
void *ocf_mpool_new(struct ocf_mpool *mpool, uint32_t count);
|
||||
|
||||
/**
|
||||
* @brief Allocate new items of memory pool with specified allocation flag
|
||||
*
|
||||
* @param mpool OCF memory pool reference
|
||||
* @param count Count of elements to be allocated
|
||||
* @param flags Kernel allocation falgs
|
||||
*
|
||||
* @return Pointer to the new items
|
||||
*/
|
||||
void *ocf_mpool_new_f(struct ocf_mpool *mpool, uint32_t count, int flags);
|
||||
|
||||
/**
|
||||
* @brief Free existing items of memory pool
|
||||
*
|
||||
* @param mpool OCF memory pool reference
|
||||
* @param items Items to be freed
|
||||
* @param count - Count of elements to be free
|
||||
*/
|
||||
void ocf_mpool_del(struct ocf_mpool *mpool, void *items, uint32_t count);
|
||||
|
||||
#endif /* __OCF_UTILITIES_H__ */
|
||||
Reference in New Issue
Block a user