diff options
Diffstat (limited to 'drivers/md/dm-raid.c')
-rw-r--r-- | drivers/md/dm-raid.c | 147 |
1 files changed, 123 insertions, 24 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 017c34d78d61..982e3e390c45 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include "md.h" | 11 | #include "md.h" |
12 | #include "raid1.h" | 12 | #include "raid1.h" |
13 | #include "raid5.h" | 13 | #include "raid5.h" |
14 | #include "raid10.h" | ||
14 | #include "bitmap.h" | 15 | #include "bitmap.h" |
15 | 16 | ||
16 | #include <linux/device-mapper.h> | 17 | #include <linux/device-mapper.h> |
@@ -52,7 +53,10 @@ struct raid_dev { | |||
52 | #define DMPF_MAX_RECOVERY_RATE 0x20 | 53 | #define DMPF_MAX_RECOVERY_RATE 0x20 |
53 | #define DMPF_MAX_WRITE_BEHIND 0x40 | 54 | #define DMPF_MAX_WRITE_BEHIND 0x40 |
54 | #define DMPF_STRIPE_CACHE 0x80 | 55 | #define DMPF_STRIPE_CACHE 0x80 |
55 | #define DMPF_REGION_SIZE 0X100 | 56 | #define DMPF_REGION_SIZE 0x100 |
57 | #define DMPF_RAID10_COPIES 0x200 | ||
58 | #define DMPF_RAID10_FORMAT 0x400 | ||
59 | |||
56 | struct raid_set { | 60 | struct raid_set { |
57 | struct dm_target *ti; | 61 | struct dm_target *ti; |
58 | 62 | ||
@@ -76,6 +80,7 @@ static struct raid_type { | |||
76 | const unsigned algorithm; /* RAID algorithm. */ | 80 | const unsigned algorithm; /* RAID algorithm. */ |
77 | } raid_types[] = { | 81 | } raid_types[] = { |
78 | {"raid1", "RAID1 (mirroring)", 0, 2, 1, 0 /* NONE */}, | 82 | {"raid1", "RAID1 (mirroring)", 0, 2, 1, 0 /* NONE */}, |
83 | {"raid10", "RAID10 (striped mirrors)", 0, 2, 10, UINT_MAX /* Varies */}, | ||
79 | {"raid4", "RAID4 (dedicated parity disk)", 1, 2, 5, ALGORITHM_PARITY_0}, | 84 | {"raid4", "RAID4 (dedicated parity disk)", 1, 2, 5, ALGORITHM_PARITY_0}, |
80 | {"raid5_la", "RAID5 (left asymmetric)", 1, 2, 5, ALGORITHM_LEFT_ASYMMETRIC}, | 85 | {"raid5_la", "RAID5 (left asymmetric)", 1, 2, 5, ALGORITHM_LEFT_ASYMMETRIC}, |
81 | {"raid5_ra", "RAID5 (right asymmetric)", 1, 2, 5, ALGORITHM_RIGHT_ASYMMETRIC}, | 86 | {"raid5_ra", "RAID5 (right asymmetric)", 1, 2, 5, ALGORITHM_RIGHT_ASYMMETRIC}, |
@@ -86,6 +91,17 @@ static struct raid_type { | |||
86 | {"raid6_nc", "RAID6 (N continue)", 2, 4, 6, ALGORITHM_ROTATING_N_CONTINUE} | 91 | {"raid6_nc", "RAID6 (N continue)", 2, 4, 6, ALGORITHM_ROTATING_N_CONTINUE} |
87 | }; | 92 | }; |
88 | 93 | ||
94 | static unsigned raid10_md_layout_to_copies(int layout) | ||
95 | { | ||
96 | return layout & 0xFF; | ||
97 | } | ||
98 | |||
99 | static int raid10_format_to_md_layout(char *format, unsigned copies) | ||
100 | { | ||
101 | /* 1 "far" copy, and 'copies' "near" copies */ | ||
102 | return (1 << 8) | (copies & 0xFF); | ||
103 | } | ||
104 | |||
89 | static struct raid_type *get_raid_type(char *name) | 105 | static struct raid_type *get_raid_type(char *name) |
90 | { | 106 | { |
91 | int i; | 107 | int i; |
@@ -101,20 +117,12 @@ static struct raid_set *context_alloc(struct dm_target *ti, struct raid_type *ra | |||
101 | { | 117 | { |
102 | unsigned i; | 118 | unsigned i; |
103 | struct raid_set *rs; | 119 | struct raid_set *rs; |
104 | sector_t sectors_per_dev; | ||
105 | 120 | ||
106 | if (raid_devs <= raid_type->parity_devs) { | 121 | if (raid_devs <= raid_type->parity_devs) { |
107 | ti->error = "Insufficient number of devices"; | 122 | ti->error = "Insufficient number of devices"; |
108 | return ERR_PTR(-EINVAL); | 123 | return ERR_PTR(-EINVAL); |
109 | } | 124 | } |
110 | 125 | ||
111 | sectors_per_dev = ti->len; | ||
112 | if ((raid_type->level > 1) && | ||
113 | sector_div(sectors_per_dev, (raid_devs - raid_type->parity_devs))) { | ||
114 | ti->error = "Target length not divisible by number of data devices"; | ||
115 | return ERR_PTR(-EINVAL); | ||
116 | } | ||
117 | |||
118 | rs = kzalloc(sizeof(*rs) + raid_devs * sizeof(rs->dev[0]), GFP_KERNEL); | 126 | rs = kzalloc(sizeof(*rs) + raid_devs * sizeof(rs->dev[0]), GFP_KERNEL); |
119 | if (!rs) { | 127 | if (!rs) { |
120 | ti->error = "Cannot allocate raid context"; | 128 | ti->error = "Cannot allocate raid context"; |
@@ -128,7 +136,6 @@ static struct raid_set *context_alloc(struct dm_target *ti, struct raid_type *ra | |||
128 | rs->md.raid_disks = raid_devs; | 136 | rs->md.raid_disks = raid_devs; |
129 | rs->md.level = raid_type->level; | 137 | rs->md.level = raid_type->level; |
130 | rs->md.new_level = rs->md.level; | 138 | rs->md.new_level = rs->md.level; |
131 | rs->md.dev_sectors = sectors_per_dev; | ||
132 | rs->md.layout = raid_type->algorithm; | 139 | rs->md.layout = raid_type->algorithm; |
133 | rs->md.new_layout = rs->md.layout; | 140 | rs->md.new_layout = rs->md.layout; |
134 | rs->md.delta_disks = 0; | 141 | rs->md.delta_disks = 0; |
@@ -143,6 +150,7 @@ static struct raid_set *context_alloc(struct dm_target *ti, struct raid_type *ra | |||
143 | * rs->md.external | 150 | * rs->md.external |
144 | * rs->md.chunk_sectors | 151 | * rs->md.chunk_sectors |
145 | * rs->md.new_chunk_sectors | 152 | * rs->md.new_chunk_sectors |
153 | * rs->md.dev_sectors | ||
146 | */ | 154 | */ |
147 | 155 | ||
148 | return rs; | 156 | return rs; |
@@ -347,12 +355,20 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size) | |||
347 | * [max_write_behind <sectors>] See '-write-behind=' (man mdadm) | 355 | * [max_write_behind <sectors>] See '-write-behind=' (man mdadm) |
348 | * [stripe_cache <sectors>] Stripe cache size for higher RAIDs | 356 | * [stripe_cache <sectors>] Stripe cache size for higher RAIDs |
349 | * [region_size <sectors>] Defines granularity of bitmap | 357 | * [region_size <sectors>] Defines granularity of bitmap |
358 | * | ||
359 | * RAID10-only options: | ||
360 | * [raid10_copies <# copies>] Number of copies. (Default: 2) | ||
361 | * [raid10_format <near>] Layout algorithm. (Default: near) | ||
350 | */ | 362 | */ |
351 | static int parse_raid_params(struct raid_set *rs, char **argv, | 363 | static int parse_raid_params(struct raid_set *rs, char **argv, |
352 | unsigned num_raid_params) | 364 | unsigned num_raid_params) |
353 | { | 365 | { |
366 | char *raid10_format = "near"; | ||
367 | unsigned raid10_copies = 2; | ||
354 | unsigned i, rebuild_cnt = 0; | 368 | unsigned i, rebuild_cnt = 0; |
355 | unsigned long value, region_size = 0; | 369 | unsigned long value, region_size = 0; |
370 | sector_t sectors_per_dev = rs->ti->len; | ||
371 | sector_t max_io_len; | ||
356 | char *key; | 372 | char *key; |
357 | 373 | ||
358 | /* | 374 | /* |
@@ -422,20 +438,53 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
422 | } | 438 | } |
423 | 439 | ||
424 | key = argv[i++]; | 440 | key = argv[i++]; |
441 | |||
442 | /* Parameters that take a string value are checked here. */ | ||
443 | if (!strcasecmp(key, "raid10_format")) { | ||
444 | if (rs->raid_type->level != 10) { | ||
445 | rs->ti->error = "'raid10_format' is an invalid parameter for this RAID type"; | ||
446 | return -EINVAL; | ||
447 | } | ||
448 | if (strcmp("near", argv[i])) { | ||
449 | rs->ti->error = "Invalid 'raid10_format' value given"; | ||
450 | return -EINVAL; | ||
451 | } | ||
452 | raid10_format = argv[i]; | ||
453 | rs->print_flags |= DMPF_RAID10_FORMAT; | ||
454 | continue; | ||
455 | } | ||
456 | |||
425 | if (strict_strtoul(argv[i], 10, &value) < 0) { | 457 | if (strict_strtoul(argv[i], 10, &value) < 0) { |
426 | rs->ti->error = "Bad numerical argument given in raid params"; | 458 | rs->ti->error = "Bad numerical argument given in raid params"; |
427 | return -EINVAL; | 459 | return -EINVAL; |
428 | } | 460 | } |
429 | 461 | ||
462 | /* Parameters that take a numeric value are checked here */ | ||
430 | if (!strcasecmp(key, "rebuild")) { | 463 | if (!strcasecmp(key, "rebuild")) { |
431 | rebuild_cnt++; | 464 | rebuild_cnt++; |
432 | if (((rs->raid_type->level != 1) && | 465 | |
433 | (rebuild_cnt > rs->raid_type->parity_devs)) || | 466 | switch (rs->raid_type->level) { |
434 | ((rs->raid_type->level == 1) && | 467 | case 1: |
435 | (rebuild_cnt > (rs->md.raid_disks - 1)))) { | 468 | if (rebuild_cnt >= rs->md.raid_disks) { |
436 | rs->ti->error = "Too many rebuild devices specified for given RAID type"; | 469 | rs->ti->error = "Too many rebuild devices specified"; |
470 | return -EINVAL; | ||
471 | } | ||
472 | break; | ||
473 | case 4: | ||
474 | case 5: | ||
475 | case 6: | ||
476 | if (rebuild_cnt > rs->raid_type->parity_devs) { | ||
477 | rs->ti->error = "Too many rebuild devices specified for given RAID type"; | ||
478 | return -EINVAL; | ||
479 | } | ||
480 | break; | ||
481 | case 10: | ||
482 | default: | ||
483 | DMERR("The rebuild parameter is not supported for %s", rs->raid_type->name); | ||
484 | rs->ti->error = "Rebuild not supported for this RAID type"; | ||
437 | return -EINVAL; | 485 | return -EINVAL; |
438 | } | 486 | } |
487 | |||
439 | if (value > rs->md.raid_disks) { | 488 | if (value > rs->md.raid_disks) { |
440 | rs->ti->error = "Invalid rebuild index given"; | 489 | rs->ti->error = "Invalid rebuild index given"; |
441 | return -EINVAL; | 490 | return -EINVAL; |
@@ -486,7 +535,8 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
486 | */ | 535 | */ |
487 | value /= 2; | 536 | value /= 2; |
488 | 537 | ||
489 | if (rs->raid_type->level < 5) { | 538 | if ((rs->raid_type->level != 5) && |
539 | (rs->raid_type->level != 6)) { | ||
490 | rs->ti->error = "Inappropriate argument: stripe_cache"; | 540 | rs->ti->error = "Inappropriate argument: stripe_cache"; |
491 | return -EINVAL; | 541 | return -EINVAL; |
492 | } | 542 | } |
@@ -511,6 +561,14 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
511 | } else if (!strcasecmp(key, "region_size")) { | 561 | } else if (!strcasecmp(key, "region_size")) { |
512 | rs->print_flags |= DMPF_REGION_SIZE; | 562 | rs->print_flags |= DMPF_REGION_SIZE; |
513 | region_size = value; | 563 | region_size = value; |
564 | } else if (!strcasecmp(key, "raid10_copies") && | ||
565 | (rs->raid_type->level == 10)) { | ||
566 | if ((value < 2) || (value > 0xFF)) { | ||
567 | rs->ti->error = "Bad value for 'raid10_copies'"; | ||
568 | return -EINVAL; | ||
569 | } | ||
570 | rs->print_flags |= DMPF_RAID10_COPIES; | ||
571 | raid10_copies = value; | ||
514 | } else { | 572 | } else { |
515 | DMERR("Unable to parse RAID parameter: %s", key); | 573 | DMERR("Unable to parse RAID parameter: %s", key); |
516 | rs->ti->error = "Unable to parse RAID parameters"; | 574 | rs->ti->error = "Unable to parse RAID parameters"; |
@@ -522,14 +580,33 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
522 | return -EINVAL; | 580 | return -EINVAL; |
523 | 581 | ||
524 | if (rs->md.chunk_sectors) | 582 | if (rs->md.chunk_sectors) |
525 | rs->ti->split_io = rs->md.chunk_sectors; | 583 | max_io_len = rs->md.chunk_sectors; |
526 | else | 584 | else |
527 | rs->ti->split_io = region_size; | 585 | max_io_len = region_size; |
528 | 586 | ||
529 | if (rs->md.chunk_sectors) | 587 | if (dm_set_target_max_io_len(rs->ti, max_io_len)) |
530 | rs->ti->split_io = rs->md.chunk_sectors; | 588 | return -EINVAL; |
531 | else | 589 | |
532 | rs->ti->split_io = region_size; | 590 | if (rs->raid_type->level == 10) { |
591 | if (raid10_copies > rs->md.raid_disks) { | ||
592 | rs->ti->error = "Not enough devices to satisfy specification"; | ||
593 | return -EINVAL; | ||
594 | } | ||
595 | |||
596 | /* (Len * #mirrors) / #devices */ | ||
597 | sectors_per_dev = rs->ti->len * raid10_copies; | ||
598 | sector_div(sectors_per_dev, rs->md.raid_disks); | ||
599 | |||
600 | rs->md.layout = raid10_format_to_md_layout(raid10_format, | ||
601 | raid10_copies); | ||
602 | rs->md.new_layout = rs->md.layout; | ||
603 | } else if ((rs->raid_type->level > 1) && | ||
604 | sector_div(sectors_per_dev, | ||
605 | (rs->md.raid_disks - rs->raid_type->parity_devs))) { | ||
606 | rs->ti->error = "Target length not divisible by number of data devices"; | ||
607 | return -EINVAL; | ||
608 | } | ||
609 | rs->md.dev_sectors = sectors_per_dev; | ||
533 | 610 | ||
534 | /* Assume there are no metadata devices until the drives are parsed */ | 611 | /* Assume there are no metadata devices until the drives are parsed */ |
535 | rs->md.persistent = 0; | 612 | rs->md.persistent = 0; |
@@ -552,6 +629,9 @@ static int raid_is_congested(struct dm_target_callbacks *cb, int bits) | |||
552 | if (rs->raid_type->level == 1) | 629 | if (rs->raid_type->level == 1) |
553 | return md_raid1_congested(&rs->md, bits); | 630 | return md_raid1_congested(&rs->md, bits); |
554 | 631 | ||
632 | if (rs->raid_type->level == 10) | ||
633 | return md_raid10_congested(&rs->md, bits); | ||
634 | |||
555 | return md_raid5_congested(&rs->md, bits); | 635 | return md_raid5_congested(&rs->md, bits); |
556 | } | 636 | } |
557 | 637 | ||
@@ -870,6 +950,9 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) | |||
870 | case 6: | 950 | case 6: |
871 | redundancy = rs->raid_type->parity_devs; | 951 | redundancy = rs->raid_type->parity_devs; |
872 | break; | 952 | break; |
953 | case 10: | ||
954 | redundancy = raid10_md_layout_to_copies(mddev->layout) - 1; | ||
955 | break; | ||
873 | default: | 956 | default: |
874 | ti->error = "Unknown RAID type"; | 957 | ti->error = "Unknown RAID type"; |
875 | return -EINVAL; | 958 | return -EINVAL; |
@@ -1035,12 +1118,19 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
1035 | goto bad; | 1118 | goto bad; |
1036 | } | 1119 | } |
1037 | 1120 | ||
1121 | if (ti->len != rs->md.array_sectors) { | ||
1122 | ti->error = "Array size does not match requested target length"; | ||
1123 | ret = -EINVAL; | ||
1124 | goto size_mismatch; | ||
1125 | } | ||
1038 | rs->callbacks.congested_fn = raid_is_congested; | 1126 | rs->callbacks.congested_fn = raid_is_congested; |
1039 | dm_table_add_target_callbacks(ti->table, &rs->callbacks); | 1127 | dm_table_add_target_callbacks(ti->table, &rs->callbacks); |
1040 | 1128 | ||
1041 | mddev_suspend(&rs->md); | 1129 | mddev_suspend(&rs->md); |
1042 | return 0; | 1130 | return 0; |
1043 | 1131 | ||
1132 | size_mismatch: | ||
1133 | md_stop(&rs->md); | ||
1044 | bad: | 1134 | bad: |
1045 | context_free(rs); | 1135 | context_free(rs); |
1046 | 1136 | ||
@@ -1067,7 +1157,7 @@ static int raid_map(struct dm_target *ti, struct bio *bio, union map_info *map_c | |||
1067 | } | 1157 | } |
1068 | 1158 | ||
1069 | static int raid_status(struct dm_target *ti, status_type_t type, | 1159 | static int raid_status(struct dm_target *ti, status_type_t type, |
1070 | char *result, unsigned maxlen) | 1160 | unsigned status_flags, char *result, unsigned maxlen) |
1071 | { | 1161 | { |
1072 | struct raid_set *rs = ti->private; | 1162 | struct raid_set *rs = ti->private; |
1073 | unsigned raid_param_cnt = 1; /* at least 1 for chunksize */ | 1163 | unsigned raid_param_cnt = 1; /* at least 1 for chunksize */ |
@@ -1189,6 +1279,13 @@ static int raid_status(struct dm_target *ti, status_type_t type, | |||
1189 | DMEMIT(" region_size %lu", | 1279 | DMEMIT(" region_size %lu", |
1190 | rs->md.bitmap_info.chunksize >> 9); | 1280 | rs->md.bitmap_info.chunksize >> 9); |
1191 | 1281 | ||
1282 | if (rs->print_flags & DMPF_RAID10_COPIES) | ||
1283 | DMEMIT(" raid10_copies %u", | ||
1284 | raid10_md_layout_to_copies(rs->md.layout)); | ||
1285 | |||
1286 | if (rs->print_flags & DMPF_RAID10_FORMAT) | ||
1287 | DMEMIT(" raid10_format near"); | ||
1288 | |||
1192 | DMEMIT(" %d", rs->md.raid_disks); | 1289 | DMEMIT(" %d", rs->md.raid_disks); |
1193 | for (i = 0; i < rs->md.raid_disks; i++) { | 1290 | for (i = 0; i < rs->md.raid_disks; i++) { |
1194 | if (rs->dev[i].meta_dev) | 1291 | if (rs->dev[i].meta_dev) |
@@ -1263,7 +1360,7 @@ static void raid_resume(struct dm_target *ti) | |||
1263 | 1360 | ||
1264 | static struct target_type raid_target = { | 1361 | static struct target_type raid_target = { |
1265 | .name = "raid", | 1362 | .name = "raid", |
1266 | .version = {1, 2, 0}, | 1363 | .version = {1, 3, 0}, |
1267 | .module = THIS_MODULE, | 1364 | .module = THIS_MODULE, |
1268 | .ctr = raid_ctr, | 1365 | .ctr = raid_ctr, |
1269 | .dtr = raid_dtr, | 1366 | .dtr = raid_dtr, |
@@ -1290,6 +1387,8 @@ module_init(dm_raid_init); | |||
1290 | module_exit(dm_raid_exit); | 1387 | module_exit(dm_raid_exit); |
1291 | 1388 | ||
1292 | MODULE_DESCRIPTION(DM_NAME " raid4/5/6 target"); | 1389 | MODULE_DESCRIPTION(DM_NAME " raid4/5/6 target"); |
1390 | MODULE_ALIAS("dm-raid1"); | ||
1391 | MODULE_ALIAS("dm-raid10"); | ||
1293 | MODULE_ALIAS("dm-raid4"); | 1392 | MODULE_ALIAS("dm-raid4"); |
1294 | MODULE_ALIAS("dm-raid5"); | 1393 | MODULE_ALIAS("dm-raid5"); |
1295 | MODULE_ALIAS("dm-raid6"); | 1394 | MODULE_ALIAS("dm-raid6"); |