linux/drivers/md/dm-raid1.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2003 Sistina Software Limited.
 * Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
 *
 * This file is released under the GPL.
 */

#include "dm-bio-record.h"

#include <linux/init.h>
#include <linux/mempool.h>
#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/device-mapper.h>
#include <linux/dm-io.h>
#include <linux/dm-dirty-log.h>
#include <linux/dm-kcopyd.h>
#include <linux/dm-region-hash.h>

static struct workqueue_struct *dm_raid1_wq;

#define DM_MSG_PREFIX

#define MAX_RECOVERY

#define MAX_NR_MIRRORS

#define DM_RAID1_HANDLE_ERRORS
#define DM_RAID1_KEEP_LOG
#define errors_handled(p)
#define keep_log(p)

static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);

/*
 *---------------------------------------------------------------
 * Mirror set structures.
 *---------------------------------------------------------------
 */
enum dm_raid1_error {};

struct mirror {};

struct mirror_set {};

DECLARE_DM_KCOPYD_THROTTLE_WITH_MODULE_PARM();

static void wakeup_mirrord(void *context)
{}

static void delayed_wake_fn(struct timer_list *t)
{}

static void delayed_wake(struct mirror_set *ms)
{}

static void wakeup_all_recovery_waiters(void *context)
{}

static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw)
{}

static void dispatch_bios(void *context, struct bio_list *bio_list)
{}

struct dm_raid1_bio_record {};

/*
 * Every mirror should look like this one.
 */
#define DEFAULT_MIRROR

/*
 * This is yucky.  We squirrel the mirror struct away inside
 * bi_next for read/write buffers.  This is safe since the bh
 * doesn't get submitted to the lower levels of block layer.
 */
static struct mirror *bio_get_m(struct bio *bio)
{}

static void bio_set_m(struct bio *bio, struct mirror *m)
{}

static struct mirror *get_default_mirror(struct mirror_set *ms)
{}

static void set_default_mirror(struct mirror *m)
{}

static struct mirror *get_valid_mirror(struct mirror_set *ms)
{}

/* fail_mirror
 * @m: mirror device to fail
 * @error_type: one of the enum's, DM_RAID1_*_ERROR
 *
 * If errors are being handled, record the type of
 * error encountered for this device.  If this type
 * of error has already been recorded, we can return;
 * otherwise, we must signal userspace by triggering
 * an event.  Additionally, if the device is the
 * primary device, we must choose a new primary, but
 * only if the mirror is in-sync.
 *
 * This function must not block.
 */
static void fail_mirror(struct mirror *m, enum dm_raid1_error error_type)
{}

static int mirror_flush(struct dm_target *ti)
{}

/*
 *---------------------------------------------------------------
 * Recovery.
 *
 * When a mirror is first activated we may find that some regions
 * are in the no-sync state.  We have to recover these by
 * recopying from the default mirror to all the others.
 *---------------------------------------------------------------
 */
static void recovery_complete(int read_err, unsigned long write_err,
			      void *context)
{}

static void recover(struct mirror_set *ms, struct dm_region *reg)
{}

static void reset_ms_flags(struct mirror_set *ms)
{}

static void do_recovery(struct mirror_set *ms)
{}

/*
 *---------------------------------------------------------------
 * Reads
 *---------------------------------------------------------------
 */
static struct mirror *choose_mirror(struct mirror_set *ms, sector_t sector)
{}

static int default_ok(struct mirror *m)
{}

static int mirror_available(struct mirror_set *ms, struct bio *bio)
{}

/*
 * remap a buffer to a particular mirror.
 */
static sector_t map_sector(struct mirror *m, struct bio *bio)
{}

static void map_bio(struct mirror *m, struct bio *bio)
{}

static void map_region(struct dm_io_region *io, struct mirror *m,
		       struct bio *bio)
{}

static void hold_bio(struct mirror_set *ms, struct bio *bio)
{}

/*
 *---------------------------------------------------------------
 * Reads
 *---------------------------------------------------------------
 */
static void read_callback(unsigned long error, void *context)
{}

/* Asynchronous read. */
static void read_async_bio(struct mirror *m, struct bio *bio)
{}

static inline int region_in_sync(struct mirror_set *ms, region_t region,
				 int may_block)
{}

static void do_reads(struct mirror_set *ms, struct bio_list *reads)
{}

/*
 *---------------------------------------------------------------------
 * Writes.
 *
 * We do different things with the write io depending on the
 * state of the region that it's in:
 *
 * SYNC:	increment pending, use kcopyd to write to *all* mirrors
 * RECOVERING:	delay the io until recovery completes
 * NOSYNC:	increment pending, just write to the default mirror
 *---------------------------------------------------------------------
 */
static void write_callback(unsigned long error, void *context)
{}

static void do_write(struct mirror_set *ms, struct bio *bio)
{}

static void do_writes(struct mirror_set *ms, struct bio_list *writes)
{}

static void do_failures(struct mirror_set *ms, struct bio_list *failures)
{}

static void trigger_event(struct work_struct *work)
{}

/*
 *---------------------------------------------------------------
 * kmirrord
 *---------------------------------------------------------------
 */
static void do_mirror(struct work_struct *work)
{}

/*
 *---------------------------------------------------------------
 * Target functions
 *---------------------------------------------------------------
 */
static struct mirror_set *alloc_context(unsigned int nr_mirrors,
					uint32_t region_size,
					struct dm_target *ti,
					struct dm_dirty_log *dl)
{}

static void free_context(struct mirror_set *ms, struct dm_target *ti,
			 unsigned int m)
{}

static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
		      unsigned int mirror, char **argv)
{}

/*
 * Create dirty log: log_type #log_params <log_params>
 */
static struct dm_dirty_log *create_dirty_log(struct dm_target *ti,
					     unsigned int argc, char **argv,
					     unsigned int *args_used)
{}

static int parse_features(struct mirror_set *ms, unsigned int argc, char **argv,
			  unsigned int *args_used)
{}

/*
 * Construct a mirror mapping:
 *
 * log_type #log_params <log_params>
 * #mirrors [mirror_path offset]{2,}
 * [#features <features>]
 *
 * log_type is "core" or "disk"
 * #log_params is between 1 and 3
 *
 * If present, supported features are "handle_errors" and "keep_log".
 */
static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{}

static void mirror_dtr(struct dm_target *ti)
{}

/*
 * Mirror mapping function
 */
static int mirror_map(struct dm_target *ti, struct bio *bio)
{}

static int mirror_end_io(struct dm_target *ti, struct bio *bio,
		blk_status_t *error)
{}

static void mirror_presuspend(struct dm_target *ti)
{}

static void mirror_postsuspend(struct dm_target *ti)
{}

static void mirror_resume(struct dm_target *ti)
{}

/*
 * device_status_char
 * @m: mirror device/leg we want the status of
 *
 * We return one character representing the most severe error
 * we have encountered.
 *    A => Alive - No failures
 *    D => Dead - A write failure occurred leaving mirror out-of-sync
 *    S => Sync - A sychronization failure occurred, mirror out-of-sync
 *    R => Read - A read failure occurred, mirror data unaffected
 *
 * Returns: <char>
 */
static char device_status_char(struct mirror *m)
{}


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

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

static struct target_type mirror_target =;

static int __init dm_mirror_init(void)
{}

static void __exit dm_mirror_exit(void)
{}

/* Module hooks */
module_init();
module_exit(dm_mirror_exit);

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