linux/drivers/md/dm-switch.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2010-2012 by Dell Inc.  All rights reserved.
 * Copyright (C) 2011-2013 Red Hat, Inc.
 *
 * This file is released under the GPL.
 *
 * dm-switch is a device-mapper target that maps IO to underlying block
 * devices efficiently when there are a large number of fixed-sized
 * address regions but there is no simple pattern to allow for a compact
 * mapping representation such as dm-stripe.
 */

#include <linux/device-mapper.h>

#include <linux/module.h>
#include <linux/init.h>
#include <linux/vmalloc.h>

#define DM_MSG_PREFIX

/*
 * One region_table_slot_t holds <region_entries_per_slot> region table
 * entries each of which is <region_table_entry_bits> in size.
 */
region_table_slot_t;

/*
 * A device with the offset to its start sector.
 */
struct switch_path {};

/*
 * Context block for a dm switch device.
 */
struct switch_ctx {};

static struct switch_ctx *alloc_switch_ctx(struct dm_target *ti, unsigned int nr_paths,
					   unsigned int region_size)
{}

static int alloc_region_table(struct dm_target *ti, unsigned int nr_paths)
{}

static void switch_get_position(struct switch_ctx *sctx, unsigned long region_nr,
				unsigned long *region_index, unsigned int *bit)
{}

static unsigned int switch_region_table_read(struct switch_ctx *sctx, unsigned long region_nr)
{}

/*
 * Find which path to use at given offset.
 */
static unsigned int switch_get_path_nr(struct switch_ctx *sctx, sector_t offset)
{}

static void switch_region_table_write(struct switch_ctx *sctx, unsigned long region_nr,
				      unsigned int value)
{}

/*
 * Fill the region table with an initial round robin pattern.
 */
static void initialise_region_table(struct switch_ctx *sctx)
{}

static int parse_path(struct dm_arg_set *as, struct dm_target *ti)
{}

/*
 * Destructor: Don't free the dm_target, just the ti->private data (if any).
 */
static void switch_dtr(struct dm_target *ti)
{}

/*
 * Constructor arguments:
 *   <num_paths> <region_size> <num_optional_args> [<optional_args>...]
 *   [<dev_path> <offset>]+
 *
 * Optional args are to allow for future extension: currently this
 * parameter must be 0.
 */
static int switch_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{}

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

/*
 * We need to parse hex numbers in the message as quickly as possible.
 *
 * This table-based hex parser improves performance.
 * It improves a time to load 1000000 entries compared to the condition-based
 * parser.
 *		table-based parser	condition-based parser
 * PA-RISC	0.29s			0.31s
 * Opteron	0.0495s			0.0498s
 */
static const unsigned char hex_table[256] =;

static __always_inline unsigned long parse_hex(const char **string)
{}

static int process_set_region_mappings(struct switch_ctx *sctx,
				       unsigned int argc, char **argv)
{}

/*
 * Messages are processed one-at-a-time.
 *
 * Only set_region_mappings is supported.
 */
static int switch_message(struct dm_target *ti, unsigned int argc, char **argv,
			  char *result, unsigned int maxlen)
{}

static void switch_status(struct dm_target *ti, status_type_t type,
			  unsigned int status_flags, char *result, unsigned int maxlen)
{}

/*
 * Switch ioctl:
 *
 * Passthrough all ioctls to the path for sector 0
 */
static int switch_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
{}

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

static struct target_type switch_target =;
module_dm(switch);

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