#include <linux/mm.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/rwsem.h>
#include <linux/bitops.h>
#include <linux/bitmap.h>
#include <linux/device-mapper.h>
#include "persistent-data/dm-bitset.h"
#include "persistent-data/dm-space-map.h"
#include "persistent-data/dm-block-manager.h"
#include "persistent-data/dm-transaction-manager.h"
#include "dm-clone-metadata.h"
#define DM_MSG_PREFIX …
#define SUPERBLOCK_LOCATION …
#define SUPERBLOCK_MAGIC …
#define SUPERBLOCK_CSUM_XOR …
#define DM_CLONE_MAX_CONCURRENT_LOCKS …
#define UUID_LEN …
#define DM_CLONE_MIN_METADATA_VERSION …
#define DM_CLONE_MAX_METADATA_VERSION …
struct superblock_disk { … } __packed;
struct dirty_map { … };
struct dm_clone_metadata { … };
static void sb_prepare_for_write(const struct dm_block_validator *v,
struct dm_block *b, size_t sb_block_size)
{ … }
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_all_zeroes(struct dm_block_manager *bm, bool *formatted)
{ … }
static inline int superblock_read_lock(struct dm_clone_metadata *cmd,
struct dm_block **sblock)
{ … }
static inline int superblock_write_lock_zero(struct dm_clone_metadata *cmd,
struct dm_block **sblock)
{ … }
static int __copy_sm_root(struct dm_clone_metadata *cmd)
{ … }
static void __prepare_superblock(struct dm_clone_metadata *cmd,
struct superblock_disk *sb)
{ … }
static int __open_metadata(struct dm_clone_metadata *cmd)
{ … }
static int __format_metadata(struct dm_clone_metadata *cmd)
{ … }
static int __open_or_format_metadata(struct dm_clone_metadata *cmd, bool may_format_device)
{ … }
static int __create_persistent_data_structures(struct dm_clone_metadata *cmd,
bool may_format_device)
{ … }
static void __destroy_persistent_data_structures(struct dm_clone_metadata *cmd)
{ … }
static int __dirty_map_init(struct dirty_map *dmap, unsigned long nr_words,
unsigned long nr_regions)
{ … }
static void __dirty_map_exit(struct dirty_map *dmap)
{ … }
static int dirty_map_init(struct dm_clone_metadata *cmd)
{ … }
static void dirty_map_exit(struct dm_clone_metadata *cmd)
{ … }
static int __load_bitset_in_core(struct dm_clone_metadata *cmd)
{ … }
struct dm_clone_metadata *dm_clone_metadata_open(struct block_device *bdev,
sector_t target_size,
sector_t region_size)
{ … }
void dm_clone_metadata_close(struct dm_clone_metadata *cmd)
{ … }
bool dm_clone_is_hydration_done(struct dm_clone_metadata *cmd)
{ … }
bool dm_clone_is_region_hydrated(struct dm_clone_metadata *cmd, unsigned long region_nr)
{ … }
bool dm_clone_is_range_hydrated(struct dm_clone_metadata *cmd,
unsigned long start, unsigned long nr_regions)
{ … }
unsigned int dm_clone_nr_of_hydrated_regions(struct dm_clone_metadata *cmd)
{ … }
unsigned long dm_clone_find_next_unhydrated_region(struct dm_clone_metadata *cmd,
unsigned long start)
{ … }
static int __update_metadata_word(struct dm_clone_metadata *cmd,
unsigned long *dirty_regions,
unsigned long word)
{ … }
static int __metadata_commit(struct dm_clone_metadata *cmd)
{ … }
static int __flush_dmap(struct dm_clone_metadata *cmd, struct dirty_map *dmap)
{ … }
int dm_clone_metadata_pre_commit(struct dm_clone_metadata *cmd)
{ … }
int dm_clone_metadata_commit(struct dm_clone_metadata *cmd)
{ … }
int dm_clone_set_region_hydrated(struct dm_clone_metadata *cmd, unsigned long region_nr)
{ … }
int dm_clone_cond_set_range(struct dm_clone_metadata *cmd, unsigned long start,
unsigned long nr_regions)
{ … }
int dm_clone_reload_in_core_bitset(struct dm_clone_metadata *cmd)
{ … }
bool dm_clone_changed_this_transaction(struct dm_clone_metadata *cmd)
{ … }
int dm_clone_metadata_abort(struct dm_clone_metadata *cmd)
{ … }
void dm_clone_metadata_set_read_only(struct dm_clone_metadata *cmd)
{ … }
void dm_clone_metadata_set_read_write(struct dm_clone_metadata *cmd)
{ … }
int dm_clone_get_free_metadata_block_count(struct dm_clone_metadata *cmd,
dm_block_t *result)
{ … }
int dm_clone_get_metadata_dev_size(struct dm_clone_metadata *cmd,
dm_block_t *result)
{ … }