linux/drivers/md/dm-era-target.c

// SPDX-License-Identifier: GPL-2.0-only
#include "dm.h"
#include "persistent-data/dm-transaction-manager.h"
#include "persistent-data/dm-bitset.h"
#include "persistent-data/dm-space-map.h"

#include <linux/dm-io.h>
#include <linux/dm-kcopyd.h>
#include <linux/init.h>
#include <linux/mempool.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>

#define DM_MSG_PREFIX

#define SUPERBLOCK_LOCATION
#define SUPERBLOCK_MAGIC
#define SUPERBLOCK_CSUM_XOR
#define MIN_ERA_VERSION
#define MAX_ERA_VERSION
#define INVALID_WRITESET_ROOT
#define MIN_BLOCK_SIZE

/*
 *--------------------------------------------------------------
 * Writeset
 *--------------------------------------------------------------
 */
struct writeset_metadata {};

struct writeset {};

/*
 * This does not free off the on disk bitset as this will normally be done
 * after digesting into the era array.
 */
static void writeset_free(struct writeset *ws)
{}

static int setup_on_disk_bitset(struct dm_disk_bitset *info,
				unsigned int nr_bits, dm_block_t *root)
{}

static size_t bitset_size(unsigned int nr_bits)
{}

/*
 * Allocates memory for the in core bitset.
 */
static int writeset_alloc(struct writeset *ws, dm_block_t nr_blocks)
{}

/*
 * Wipes the in-core bitset, and creates a new on disk bitset.
 */
static int writeset_init(struct dm_disk_bitset *info, struct writeset *ws,
			 dm_block_t nr_blocks)
{}

static bool writeset_marked(struct writeset *ws, dm_block_t block)
{}

static int writeset_marked_on_disk(struct dm_disk_bitset *info,
				   struct writeset_metadata *m, dm_block_t block,
				   bool *result)
{}

/*
 * Returns < 0 on error, 0 if the bit wasn't previously set, 1 if it was.
 */
static int writeset_test_and_set(struct dm_disk_bitset *info,
				 struct writeset *ws, uint32_t block)
{}

/*
 *--------------------------------------------------------------
 * On disk metadata layout
 *--------------------------------------------------------------
 */
#define SPACE_MAP_ROOT_SIZE
#define UUID_LEN

struct writeset_disk {} __packed;

struct superblock_disk {} __packed;

/*
 *--------------------------------------------------------------
 * Superblock validation
 *--------------------------------------------------------------
 */
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 superblock_disk *disk)
{}

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 =;

/*
 *--------------------------------------------------------------
 * Low level metadata handling
 *--------------------------------------------------------------
 */
#define DM_ERA_METADATA_BLOCK_SIZE
#define ERA_MAX_CONCURRENT_LOCKS

struct era_metadata {};

static int superblock_read_lock(struct era_metadata *md,
				struct dm_block **sblock)
{}

static int superblock_lock_zero(struct era_metadata *md,
				struct dm_block **sblock)
{}

static int superblock_lock(struct era_metadata *md,
			   struct dm_block **sblock)
{}

/* FIXME: duplication with cache and thin */
static int superblock_all_zeroes(struct dm_block_manager *bm, bool *result)
{}

/*----------------------------------------------------------------*/

static void ws_pack(const struct writeset_metadata *core, struct writeset_disk *disk)
{}

static void ws_unpack(const struct writeset_disk *disk, struct writeset_metadata *core)
{}

static void ws_inc(void *context, const void *value, unsigned int count)
{}

static void ws_dec(void *context, const void *value, unsigned int count)
{}

static int ws_eq(void *context, const void *value1, const void *value2)
{}

/*----------------------------------------------------------------*/

static void setup_writeset_tree_info(struct era_metadata *md)
{}

static void setup_era_array_info(struct era_metadata *md)
{}

static void setup_infos(struct era_metadata *md)
{}

/*----------------------------------------------------------------*/

static int create_fresh_metadata(struct era_metadata *md)
{}

static int save_sm_root(struct era_metadata *md)
{}

static void copy_sm_root(struct era_metadata *md, struct superblock_disk *disk)
{}

/*
 * Writes a superblock, including the static fields that don't get updated
 * with every commit (possible optimisation here).  'md' should be fully
 * constructed when this is called.
 */
static void prepare_superblock(struct era_metadata *md, struct superblock_disk *disk)
{}

static int write_superblock(struct era_metadata *md)
{}

/*
 * Assumes block_size and the infos are set.
 */
static int format_metadata(struct era_metadata *md)
{}

static int open_metadata(struct era_metadata *md)
{}

static int open_or_format_metadata(struct era_metadata *md,
				   bool may_format)
{}

static int create_persistent_data_objects(struct era_metadata *md,
					  bool may_format)
{}

static void destroy_persistent_data_objects(struct era_metadata *md)
{}

/*
 * This waits until all era_map threads have picked up the new filter.
 */
static void swap_writeset(struct era_metadata *md, struct writeset *new_writeset)
{}

/*
 *------------------------------------------------------------------------
 * Writesets get 'digested' into the main era array.
 *
 * We're using a coroutine here so the worker thread can do the digestion,
 * thus avoiding synchronisation of the metadata.  Digesting a whole
 * writeset in one go would cause too much latency.
 *------------------------------------------------------------------------
 */
struct digest {};

static int metadata_digest_lookup_writeset(struct era_metadata *md,
					   struct digest *d);

static int metadata_digest_remove_writeset(struct era_metadata *md,
					   struct digest *d)
{}

#define INSERTS_PER_STEP

static int metadata_digest_transcribe_writeset(struct era_metadata *md,
					       struct digest *d)
{}

static int metadata_digest_lookup_writeset(struct era_metadata *md,
					   struct digest *d)
{}

static int metadata_digest_start(struct era_metadata *md, struct digest *d)
{}

/*
 *-----------------------------------------------------------------
 * High level metadata interface.  Target methods should use these,
 * and not the lower level ones.
 *-----------------------------------------------------------------
 */
static struct era_metadata *metadata_open(struct block_device *bdev,
					  sector_t block_size,
					  bool may_format)
{}

static void metadata_close(struct era_metadata *md)
{}

static bool valid_nr_blocks(dm_block_t n)
{}

static int metadata_resize(struct era_metadata *md, void *arg)
{}

static int metadata_era_archive(struct era_metadata *md)
{}

static struct writeset *next_writeset(struct era_metadata *md)
{}

static int metadata_new_era(struct era_metadata *md)
{}

static int metadata_era_rollover(struct era_metadata *md)
{}

static bool metadata_current_marked(struct era_metadata *md, dm_block_t block)
{}

static int metadata_commit(struct era_metadata *md)
{}

static int metadata_checkpoint(struct era_metadata *md)
{}

/*
 * Metadata snapshots allow userland to access era data.
 */
static int metadata_take_snap(struct era_metadata *md)
{}

static int metadata_drop_snap(struct era_metadata *md)
{}

struct metadata_stats {};

static int metadata_get_stats(struct era_metadata *md, void *ptr)
{}

/*----------------------------------------------------------------*/

struct era {};

struct rpc {};

/*
 *---------------------------------------------------------------
 * Remapping.
 *---------------------------------------------------------------
 */
static bool block_size_is_power_of_two(struct era *era)
{}

static dm_block_t get_block(struct era *era, struct bio *bio)
{}

static void remap_to_origin(struct era *era, struct bio *bio)
{}

/*
 *--------------------------------------------------------------
 * Worker thread
 *--------------------------------------------------------------
 */
static void wake_worker(struct era *era)
{}

static void process_old_eras(struct era *era)
{}

static void process_deferred_bios(struct era *era)
{}

static void process_rpc_calls(struct era *era)
{}

static void kick_off_digest(struct era *era)
{}

static void do_work(struct work_struct *ws)
{}

static void defer_bio(struct era *era, struct bio *bio)
{}

/*
 * Make an rpc call to the worker to change the metadata.
 */
static int perform_rpc(struct era *era, struct rpc *rpc)
{}

static int in_worker0(struct era *era, int (*fn)(struct era_metadata *md))
{}

static int in_worker1(struct era *era,
		      int (*fn)(struct era_metadata *md, void *ref), void *arg)
{}

static void start_worker(struct era *era)
{}

static void stop_worker(struct era *era)
{}

/*
 *--------------------------------------------------------------
 * Target methods
 *--------------------------------------------------------------
 */
static void era_destroy(struct era *era)
{}

static dm_block_t calc_nr_blocks(struct era *era)
{}

static bool valid_block_size(dm_block_t block_size)
{}

/*
 * <metadata dev> <data dev> <data block size (sectors)>
 */
static int era_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{}

static void era_dtr(struct dm_target *ti)
{}

static int era_map(struct dm_target *ti, struct bio *bio)
{}

static void era_postsuspend(struct dm_target *ti)
{}

static int era_preresume(struct dm_target *ti)
{}

/*
 * Status format:
 *
 * <metadata block size> <#used metadata blocks>/<#total metadata blocks>
 * <current era> <held metadata root | '-'>
 */
static void era_status(struct dm_target *ti, status_type_t type,
		       unsigned int status_flags, char *result, unsigned int maxlen)
{}

static int era_message(struct dm_target *ti, unsigned int argc, char **argv,
		       char *result, unsigned int maxlen)
{}

static sector_t get_dev_size(struct dm_dev *dev)
{}

static int era_iterate_devices(struct dm_target *ti,
			       iterate_devices_callout_fn fn, void *data)
{}

static void era_io_hints(struct dm_target *ti, struct queue_limits *limits)
{}

/*----------------------------------------------------------------*/

static struct target_type era_target =;
module_dm(era);

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();