11
11
#include "md.h"
12
12
#include "raid1.h"
13
13
#include "raid5.h"
14
+ #include "raid10.h"
14
15
#include "bitmap.h"
15
16
16
17
#include <linux/device-mapper.h>
@@ -52,7 +53,10 @@ struct raid_dev {
52
53
#define DMPF_MAX_RECOVERY_RATE 0x20
53
54
#define DMPF_MAX_WRITE_BEHIND 0x40
54
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
60
struct raid_set {
57
61
struct dm_target * ti ;
58
62
@@ -76,6 +80,7 @@ static struct raid_type {
76
80
const unsigned algorithm ; /* RAID algorithm. */
77
81
} raid_types [] = {
78
82
{"raid1" , "RAID1 (mirroring)" , 0 , 2 , 1 , 0 /* NONE */ },
83
+ {"raid10" , "RAID10 (striped mirrors)" , 0 , 2 , 10 , UINT_MAX /* Varies */ },
79
84
{"raid4" , "RAID4 (dedicated parity disk)" , 1 , 2 , 5 , ALGORITHM_PARITY_0 },
80
85
{"raid5_la" , "RAID5 (left asymmetric)" , 1 , 2 , 5 , ALGORITHM_LEFT_ASYMMETRIC },
81
86
{"raid5_ra" , "RAID5 (right asymmetric)" , 1 , 2 , 5 , ALGORITHM_RIGHT_ASYMMETRIC },
@@ -86,6 +91,17 @@ static struct raid_type {
86
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
105
static struct raid_type * get_raid_type (char * name )
90
106
{
91
107
int i ;
@@ -339,10 +355,16 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
339
355
* [max_write_behind <sectors>] See '-write-behind=' (man mdadm)
340
356
* [stripe_cache <sectors>] Stripe cache size for higher RAIDs
341
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)
342
362
*/
343
363
static int parse_raid_params (struct raid_set * rs , char * * argv ,
344
364
unsigned num_raid_params )
345
365
{
366
+ char * raid10_format = "near" ;
367
+ unsigned raid10_copies = 2 ;
346
368
unsigned i , rebuild_cnt = 0 ;
347
369
unsigned long value , region_size = 0 ;
348
370
sector_t sectors_per_dev = rs -> ti -> len ;
@@ -416,11 +438,28 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
416
438
}
417
439
418
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
+
419
457
if (strict_strtoul (argv [i ], 10 , & value ) < 0 ) {
420
458
rs -> ti -> error = "Bad numerical argument given in raid params" ;
421
459
return - EINVAL ;
422
460
}
423
461
462
+ /* Parameters that take a numeric value are checked here */
424
463
if (!strcasecmp (key , "rebuild" )) {
425
464
rebuild_cnt ++ ;
426
465
@@ -439,6 +478,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
439
478
return - EINVAL ;
440
479
}
441
480
break ;
481
+ case 10 :
442
482
default :
443
483
DMERR ("The rebuild parameter is not supported for %s" , rs -> raid_type -> name );
444
484
rs -> ti -> error = "Rebuild not supported for this RAID type" ;
@@ -495,7 +535,8 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
495
535
*/
496
536
value /= 2 ;
497
537
498
- if (rs -> raid_type -> level < 5 ) {
538
+ if ((rs -> raid_type -> level != 5 ) &&
539
+ (rs -> raid_type -> level != 6 )) {
499
540
rs -> ti -> error = "Inappropriate argument: stripe_cache" ;
500
541
return - EINVAL ;
501
542
}
@@ -520,6 +561,14 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
520
561
} else if (!strcasecmp (key , "region_size" )) {
521
562
rs -> print_flags |= DMPF_REGION_SIZE ;
522
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 ;
523
572
} else {
524
573
DMERR ("Unable to parse RAID parameter: %s" , key );
525
574
rs -> ti -> error = "Unable to parse RAID parameters" ;
@@ -538,8 +587,22 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
538
587
if (dm_set_target_max_io_len (rs -> ti , max_io_len ))
539
588
return - EINVAL ;
540
589
541
- if ((rs -> raid_type -> level > 1 ) &&
542
- sector_div (sectors_per_dev , (rs -> md .raid_disks - rs -> raid_type -> parity_devs ))) {
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 ))) {
543
606
rs -> ti -> error = "Target length not divisible by number of data devices" ;
544
607
return - EINVAL ;
545
608
}
@@ -566,6 +629,9 @@ static int raid_is_congested(struct dm_target_callbacks *cb, int bits)
566
629
if (rs -> raid_type -> level == 1 )
567
630
return md_raid1_congested (& rs -> md , bits );
568
631
632
+ if (rs -> raid_type -> level == 10 )
633
+ return md_raid10_congested (& rs -> md , bits );
634
+
569
635
return md_raid5_congested (& rs -> md , bits );
570
636
}
571
637
@@ -884,6 +950,9 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
884
950
case 6 :
885
951
redundancy = rs -> raid_type -> parity_devs ;
886
952
break ;
953
+ case 10 :
954
+ redundancy = raid10_md_layout_to_copies (mddev -> layout ) - 1 ;
955
+ break ;
887
956
default :
888
957
ti -> error = "Unknown RAID type" ;
889
958
return - EINVAL ;
@@ -1049,12 +1118,19 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
1049
1118
goto bad ;
1050
1119
}
1051
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
+ }
1052
1126
rs -> callbacks .congested_fn = raid_is_congested ;
1053
1127
dm_table_add_target_callbacks (ti -> table , & rs -> callbacks );
1054
1128
1055
1129
mddev_suspend (& rs -> md );
1056
1130
return 0 ;
1057
1131
1132
+ size_mismatch :
1133
+ md_stop (& rs -> md );
1058
1134
bad :
1059
1135
context_free (rs );
1060
1136
@@ -1203,6 +1279,13 @@ static int raid_status(struct dm_target *ti, status_type_t type,
1203
1279
DMEMIT (" region_size %lu" ,
1204
1280
rs -> md .bitmap_info .chunksize >> 9 );
1205
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
+
1206
1289
DMEMIT (" %d" , rs -> md .raid_disks );
1207
1290
for (i = 0 ; i < rs -> md .raid_disks ; i ++ ) {
1208
1291
if (rs -> dev [i ].meta_dev )
@@ -1277,7 +1360,7 @@ static void raid_resume(struct dm_target *ti)
1277
1360
1278
1361
static struct target_type raid_target = {
1279
1362
.name = "raid" ,
1280
- .version = {1 , 2 , 0 },
1363
+ .version = {1 , 3 , 0 },
1281
1364
.module = THIS_MODULE ,
1282
1365
.ctr = raid_ctr ,
1283
1366
.dtr = raid_dtr ,
@@ -1304,6 +1387,8 @@ module_init(dm_raid_init);
1304
1387
module_exit (dm_raid_exit );
1305
1388
1306
1389
MODULE_DESCRIPTION (DM_NAME " raid4/5/6 target" );
1390
+ MODULE_ALIAS ("dm-raid1" );
1391
+ MODULE_ALIAS ("dm-raid10" );
1307
1392
MODULE_ALIAS ("dm-raid4" );
1308
1393
MODULE_ALIAS ("dm-raid5" );
1309
1394
MODULE_ALIAS ("dm-raid6" );
0 commit comments