Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8e6afa2 authored by Jonathan E Brassow's avatar Jonathan E Brassow Committed by Linus Torvalds
Browse files

dm raid1: add handle_errors feature flag



This patch adds the ability to specify desired features in the mirror
constructor/mapping table.

The first feature of interest is "handle_errors".  Currently, mirroring will
ignore any I/O errors from the devices.  Subsequent patches will check for
this flag and handle the errors.  If flag/feature is not present, mirror will
do nothing - maintaining backwards compatibility.

Signed-off-by: default avatarJonathan E Brassow <jbrassow@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 315dcc22
Loading
Loading
Loading
Loading
+63 −2
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@

#define DM_MSG_PREFIX "raid1"

#define DM_RAID1_HANDLE_ERRORS 0x01

static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);

/*-----------------------------------------------------------------
@@ -118,6 +120,7 @@ struct mirror_set {
	struct list_head list;
	struct region_hash rh;
	struct kcopyd_client *kcopyd_client;
	uint64_t features;

	spinlock_t lock;	/* protects the next two lists */
	struct bio_list reads;
@@ -1010,14 +1013,54 @@ static struct dirty_log *create_dirty_log(struct dm_target *ti,
	return dl;
}

static int parse_features(struct mirror_set *ms, unsigned argc, char **argv,
			  unsigned *args_used)
{
	unsigned num_features;
	struct dm_target *ti = ms->ti;

	*args_used = 0;

	if (!argc)
		return 0;

	if (sscanf(argv[0], "%u", &num_features) != 1) {
		ti->error = "Invalid number of features";
		return -EINVAL;
	}

	argc--;
	argv++;
	(*args_used)++;

	if (num_features > argc) {
		ti->error = "Not enough arguments to support feature count";
		return -EINVAL;
	}

	if (!strcmp("handle_errors", argv[0]))
		ms->features |= DM_RAID1_HANDLE_ERRORS;
	else {
		ti->error = "Unrecognised feature requested";
		return -EINVAL;
	}

	(*args_used)++;

	return 0;
}

/*
 * 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, features must be "handle_errors".
 */
#define DM_IO_PAGES 64
static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
@@ -1043,8 +1086,8 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)

	argv++, argc--;

	if (argc != nr_mirrors * 2) {
		ti->error = "Wrong number of mirror arguments";
	if (argc < nr_mirrors * 2) {
		ti->error = "Too few mirror arguments";
		dm_destroy_dirty_log(dl);
		return -EINVAL;
	}
@@ -1077,6 +1120,21 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
	}
	INIT_WORK(&ms->kmirrord_work, do_mirror);

	r = parse_features(ms, argc, argv, &args_used);
	if (r) {
		free_context(ms, ti, ms->nr_mirrors);
		return r;
	}

	argv += args_used;
	argc -= args_used;

	if (argc) {
		ti->error = "Too many mirror arguments";
		free_context(ms, ti, ms->nr_mirrors);
		return -EINVAL;
	}

	r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
	if (r) {
		destroy_workqueue(ms->kmirrord_wq);
@@ -1230,6 +1288,9 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
		for (m = 0; m < ms->nr_mirrors; m++)
			DMEMIT(" %s %llu", ms->mirror[m].dev->name,
				(unsigned long long)ms->mirror[m].offset);

		if (ms->features & DM_RAID1_HANDLE_ERRORS)
			DMEMIT(" 1 handle_errors");
	}

	return 0;