aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-raid1.c
diff options
context:
space:
mode:
authorJonathan E Brassow <jbrassow@redhat.com>2007-05-09 05:32:59 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-09 15:30:47 -0400
commita8e6afa2363de7ee0dea1a3297f6236f421c2dd4 (patch)
treef0559bd5e25dbafaee331815c75774fa0834252b /drivers/md/dm-raid1.c
parent315dcc226f066c1d3cef79283dcde807fe0e32d1 (diff)
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: Jonathan E Brassow <jbrassow@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/md/dm-raid1.c')
-rw-r--r--drivers/md/dm-raid1.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index cb3f318a3692..2a3e2f80aa4b 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -22,6 +22,8 @@
22 22
23#define DM_MSG_PREFIX "raid1" 23#define DM_MSG_PREFIX "raid1"
24 24
25#define DM_RAID1_HANDLE_ERRORS 0x01
26
25static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped); 27static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);
26 28
27/*----------------------------------------------------------------- 29/*-----------------------------------------------------------------
@@ -118,6 +120,7 @@ struct mirror_set {
118 struct list_head list; 120 struct list_head list;
119 struct region_hash rh; 121 struct region_hash rh;
120 struct kcopyd_client *kcopyd_client; 122 struct kcopyd_client *kcopyd_client;
123 uint64_t features;
121 124
122 spinlock_t lock; /* protects the next two lists */ 125 spinlock_t lock; /* protects the next two lists */
123 struct bio_list reads; 126 struct bio_list reads;
@@ -1010,14 +1013,54 @@ static struct dirty_log *create_dirty_log(struct dm_target *ti,
1010 return dl; 1013 return dl;
1011} 1014}
1012 1015
1016static int parse_features(struct mirror_set *ms, unsigned argc, char **argv,
1017 unsigned *args_used)
1018{
1019 unsigned num_features;
1020 struct dm_target *ti = ms->ti;
1021
1022 *args_used = 0;
1023
1024 if (!argc)
1025 return 0;
1026
1027 if (sscanf(argv[0], "%u", &num_features) != 1) {
1028 ti->error = "Invalid number of features";
1029 return -EINVAL;
1030 }
1031
1032 argc--;
1033 argv++;
1034 (*args_used)++;
1035
1036 if (num_features > argc) {
1037 ti->error = "Not enough arguments to support feature count";
1038 return -EINVAL;
1039 }
1040
1041 if (!strcmp("handle_errors", argv[0]))
1042 ms->features |= DM_RAID1_HANDLE_ERRORS;
1043 else {
1044 ti->error = "Unrecognised feature requested";
1045 return -EINVAL;
1046 }
1047
1048 (*args_used)++;
1049
1050 return 0;
1051}
1052
1013/* 1053/*
1014 * Construct a mirror mapping: 1054 * Construct a mirror mapping:
1015 * 1055 *
1016 * log_type #log_params <log_params> 1056 * log_type #log_params <log_params>
1017 * #mirrors [mirror_path offset]{2,} 1057 * #mirrors [mirror_path offset]{2,}
1058 * [#features <features>]
1018 * 1059 *
1019 * log_type is "core" or "disk" 1060 * log_type is "core" or "disk"
1020 * #log_params is between 1 and 3 1061 * #log_params is between 1 and 3
1062 *
1063 * If present, features must be "handle_errors".
1021 */ 1064 */
1022#define DM_IO_PAGES 64 1065#define DM_IO_PAGES 64
1023static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) 1066static 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)
1043 1086
1044 argv++, argc--; 1087 argv++, argc--;
1045 1088
1046 if (argc != nr_mirrors * 2) { 1089 if (argc < nr_mirrors * 2) {
1047 ti->error = "Wrong number of mirror arguments"; 1090 ti->error = "Too few mirror arguments";
1048 dm_destroy_dirty_log(dl); 1091 dm_destroy_dirty_log(dl);
1049 return -EINVAL; 1092 return -EINVAL;
1050 } 1093 }
@@ -1077,6 +1120,21 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1077 } 1120 }
1078 INIT_WORK(&ms->kmirrord_work, do_mirror); 1121 INIT_WORK(&ms->kmirrord_work, do_mirror);
1079 1122
1123 r = parse_features(ms, argc, argv, &args_used);
1124 if (r) {
1125 free_context(ms, ti, ms->nr_mirrors);
1126 return r;
1127 }
1128
1129 argv += args_used;
1130 argc -= args_used;
1131
1132 if (argc) {
1133 ti->error = "Too many mirror arguments";
1134 free_context(ms, ti, ms->nr_mirrors);
1135 return -EINVAL;
1136 }
1137
1080 r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client); 1138 r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
1081 if (r) { 1139 if (r) {
1082 destroy_workqueue(ms->kmirrord_wq); 1140 destroy_workqueue(ms->kmirrord_wq);
@@ -1230,6 +1288,9 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
1230 for (m = 0; m < ms->nr_mirrors; m++) 1288 for (m = 0; m < ms->nr_mirrors; m++)
1231 DMEMIT(" %s %llu", ms->mirror[m].dev->name, 1289 DMEMIT(" %s %llu", ms->mirror[m].dev->name,
1232 (unsigned long long)ms->mirror[m].offset); 1290 (unsigned long long)ms->mirror[m].offset);
1291
1292 if (ms->features & DM_RAID1_HANDLE_ERRORS)
1293 DMEMIT(" 1 handle_errors");
1233 } 1294 }
1234 1295
1235 return 0; 1296 return 0;