diff options
author | Jonathan E Brassow <jbrassow@redhat.com> | 2007-05-09 05:32:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-09 15:30:47 -0400 |
commit | a8e6afa2363de7ee0dea1a3297f6236f421c2dd4 (patch) | |
tree | f0559bd5e25dbafaee331815c75774fa0834252b /drivers | |
parent | 315dcc226f066c1d3cef79283dcde807fe0e32d1 (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')
-rw-r--r-- | drivers/md/dm-raid1.c | 65 |
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 | |||
25 | static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped); | 27 | static 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 | ||
1016 | static 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 |
1023 | static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | 1066 | 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) | |||
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; |