#include "dm-cache-metadata.h"
#include "persistent-data/dm-array.h"
#include "persistent-data/dm-bitset.h"
#include "persistent-data/dm-space-map.h"
#include "persistent-data/dm-space-map-disk.h"
#include "persistent-data/dm-transaction-manager.h"
#include <linux/device-mapper.h>
#include <linux/refcount.h>
#define DM_MSG_PREFIX …
#define CACHE_SUPERBLOCK_MAGIC …
#define CACHE_SUPERBLOCK_LOCATION …
#define MIN_CACHE_VERSION …
#define MAX_CACHE_VERSION …
#define CACHE_MAX_CONCURRENT_LOCKS …
#define SPACE_MAP_ROOT_SIZE …
enum superblock_flag_bits { … };
enum mapping_bits { … };
struct cache_disk_superblock { … } __packed;
struct dm_cache_metadata { … };
#define SUPERBLOCK_CSUM_XOR …
static void sb_prepare_for_write(const struct dm_block_validator *v,
struct dm_block *b,
size_t sb_block_size)
{ … }
static int check_metadata_version(struct cache_disk_superblock *disk_super)
{ … }
static int sb_check(const struct dm_block_validator *v,
struct dm_block *b,
size_t sb_block_size)
{ … }
static const struct dm_block_validator sb_validator = …;
static int superblock_read_lock(struct dm_cache_metadata *cmd,
struct dm_block **sblock)
{ … }
static int superblock_lock_zero(struct dm_cache_metadata *cmd,
struct dm_block **sblock)
{ … }
static int superblock_lock(struct dm_cache_metadata *cmd,
struct dm_block **sblock)
{ … }
static int __superblock_all_zeroes(struct dm_block_manager *bm, bool *result)
{ … }
static void __setup_mapping_info(struct dm_cache_metadata *cmd)
{ … }
static int __save_sm_root(struct dm_cache_metadata *cmd)
{ … }
static void __copy_sm_root(struct dm_cache_metadata *cmd,
struct cache_disk_superblock *disk_super)
{ … }
static bool separate_dirty_bits(struct dm_cache_metadata *cmd)
{ … }
static int __write_initial_superblock(struct dm_cache_metadata *cmd)
{ … }
static int __format_metadata(struct dm_cache_metadata *cmd)
{ … }
static int __check_incompat_features(struct cache_disk_superblock *disk_super,
struct dm_cache_metadata *cmd)
{ … }
static int __open_metadata(struct dm_cache_metadata *cmd)
{ … }
static int __open_or_format_metadata(struct dm_cache_metadata *cmd,
bool format_device)
{ … }
static int __create_persistent_data_objects(struct dm_cache_metadata *cmd,
bool may_format_device)
{ … }
static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd,
bool destroy_bm)
{ … }
flags_mutator;
static void update_flags(struct cache_disk_superblock *disk_super,
flags_mutator mutator)
{ … }
static unsigned long set_clean_shutdown(unsigned long flags)
{ … }
static unsigned long clear_clean_shutdown(unsigned long flags)
{ … }
static void read_superblock_fields(struct dm_cache_metadata *cmd,
struct cache_disk_superblock *disk_super)
{ … }
static int __begin_transaction_flags(struct dm_cache_metadata *cmd,
flags_mutator mutator)
{ … }
static int __begin_transaction(struct dm_cache_metadata *cmd)
{ … }
static int __commit_transaction(struct dm_cache_metadata *cmd,
flags_mutator mutator)
{ … }
#define FLAGS_MASK …
static __le64 pack_value(dm_oblock_t block, unsigned int flags)
{ … }
static void unpack_value(__le64 value_le, dm_oblock_t *block, unsigned int *flags)
{ … }
static struct dm_cache_metadata *metadata_open(struct block_device *bdev,
sector_t data_block_size,
bool may_format_device,
size_t policy_hint_size,
unsigned int metadata_version)
{ … }
static DEFINE_MUTEX(table_lock);
static LIST_HEAD(table);
static struct dm_cache_metadata *lookup(struct block_device *bdev)
{ … }
static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev,
sector_t data_block_size,
bool may_format_device,
size_t policy_hint_size,
unsigned int metadata_version)
{ … }
static bool same_params(struct dm_cache_metadata *cmd, sector_t data_block_size)
{ … }
struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev,
sector_t data_block_size,
bool may_format_device,
size_t policy_hint_size,
unsigned int metadata_version)
{ … }
void dm_cache_metadata_close(struct dm_cache_metadata *cmd)
{ … }
static int block_clean_combined_dirty(struct dm_cache_metadata *cmd, dm_cblock_t b,
bool *result)
{ … }
static int blocks_are_clean_combined_dirty(struct dm_cache_metadata *cmd,
dm_cblock_t begin, dm_cblock_t end,
bool *result)
{ … }
static int blocks_are_clean_separate_dirty(struct dm_cache_metadata *cmd,
dm_cblock_t begin, dm_cblock_t end,
bool *result)
{ … }
static int blocks_are_unmapped_or_clean(struct dm_cache_metadata *cmd,
dm_cblock_t begin, dm_cblock_t end,
bool *result)
{ … }
static bool cmd_write_lock(struct dm_cache_metadata *cmd)
{ … }
#define WRITE_LOCK(cmd) …
#define WRITE_LOCK_VOID(cmd) …
#define WRITE_UNLOCK(cmd) …
static bool cmd_read_lock(struct dm_cache_metadata *cmd)
{ … }
#define READ_LOCK(cmd) …
#define READ_LOCK_VOID(cmd) …
#define READ_UNLOCK(cmd) …
int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size)
{ … }
int dm_cache_discard_bitset_resize(struct dm_cache_metadata *cmd,
sector_t discard_block_size,
dm_dblock_t new_nr_entries)
{ … }
static int __set_discard(struct dm_cache_metadata *cmd, dm_dblock_t b)
{ … }
static int __clear_discard(struct dm_cache_metadata *cmd, dm_dblock_t b)
{ … }
static int __discard(struct dm_cache_metadata *cmd,
dm_dblock_t dblock, bool discard)
{ … }
int dm_cache_set_discard(struct dm_cache_metadata *cmd,
dm_dblock_t dblock, bool discard)
{ … }
static int __load_discards(struct dm_cache_metadata *cmd,
load_discard_fn fn, void *context)
{ … }
int dm_cache_load_discards(struct dm_cache_metadata *cmd,
load_discard_fn fn, void *context)
{ … }
int dm_cache_size(struct dm_cache_metadata *cmd, dm_cblock_t *result)
{ … }
static int __remove(struct dm_cache_metadata *cmd, dm_cblock_t cblock)
{ … }
int dm_cache_remove_mapping(struct dm_cache_metadata *cmd, dm_cblock_t cblock)
{ … }
static int __insert(struct dm_cache_metadata *cmd,
dm_cblock_t cblock, dm_oblock_t oblock)
{ … }
int dm_cache_insert_mapping(struct dm_cache_metadata *cmd,
dm_cblock_t cblock, dm_oblock_t oblock)
{ … }
static bool policy_unchanged(struct dm_cache_metadata *cmd,
struct dm_cache_policy *policy)
{ … }
static bool hints_array_initialized(struct dm_cache_metadata *cmd)
{ … }
static bool hints_array_available(struct dm_cache_metadata *cmd,
struct dm_cache_policy *policy)
{ … }
static int __load_mapping_v1(struct dm_cache_metadata *cmd,
uint64_t cb, bool hints_valid,
struct dm_array_cursor *mapping_cursor,
struct dm_array_cursor *hint_cursor,
load_mapping_fn fn, void *context)
{ … }
static int __load_mapping_v2(struct dm_cache_metadata *cmd,
uint64_t cb, bool hints_valid,
struct dm_array_cursor *mapping_cursor,
struct dm_array_cursor *hint_cursor,
struct dm_bitset_cursor *dirty_cursor,
load_mapping_fn fn, void *context)
{ … }
static int __load_mappings(struct dm_cache_metadata *cmd,
struct dm_cache_policy *policy,
load_mapping_fn fn, void *context)
{ … }
int dm_cache_load_mappings(struct dm_cache_metadata *cmd,
struct dm_cache_policy *policy,
load_mapping_fn fn, void *context)
{ … }
static int __dump_mapping(void *context, uint64_t cblock, void *leaf)
{ … }
static int __dump_mappings(struct dm_cache_metadata *cmd)
{ … }
void dm_cache_dump(struct dm_cache_metadata *cmd)
{ … }
int dm_cache_changed_this_transaction(struct dm_cache_metadata *cmd)
{ … }
static int __dirty(struct dm_cache_metadata *cmd, dm_cblock_t cblock, bool dirty)
{ … }
static int __set_dirty_bits_v1(struct dm_cache_metadata *cmd, unsigned int nr_bits, unsigned long *bits)
{ … }
static int is_dirty_callback(uint32_t index, bool *value, void *context)
{ … }
static int __set_dirty_bits_v2(struct dm_cache_metadata *cmd, unsigned int nr_bits, unsigned long *bits)
{ … }
int dm_cache_set_dirty_bits(struct dm_cache_metadata *cmd,
unsigned int nr_bits,
unsigned long *bits)
{ … }
void dm_cache_metadata_get_stats(struct dm_cache_metadata *cmd,
struct dm_cache_statistics *stats)
{ … }
void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd,
struct dm_cache_statistics *stats)
{ … }
int dm_cache_commit(struct dm_cache_metadata *cmd, bool clean_shutdown)
{ … }
int dm_cache_get_free_metadata_block_count(struct dm_cache_metadata *cmd,
dm_block_t *result)
{ … }
int dm_cache_get_metadata_dev_size(struct dm_cache_metadata *cmd,
dm_block_t *result)
{ … }
static int get_hint(uint32_t index, void *value_le, void *context)
{ … }
static int write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy)
{ … }
int dm_cache_write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy)
{ … }
int dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result)
{ … }
void dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd)
{ … }
void dm_cache_metadata_set_read_write(struct dm_cache_metadata *cmd)
{ … }
int dm_cache_metadata_set_needs_check(struct dm_cache_metadata *cmd)
{ … }
int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result)
{ … }
int dm_cache_metadata_abort(struct dm_cache_metadata *cmd)
{ … }