aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-raid.c
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2016-05-19 12:49:25 -0400
committerMike Snitzer <snitzer@redhat.com>2016-06-13 12:00:40 -0400
commit92c83d79b07ec1c53e0c74b8a7988799e00856db (patch)
treee2c1e2ffe9727ce5e0e0dee52ba8652f2ab6bafc /drivers/md/dm-raid.c
parent73c6f239a86271c17d77f826a0c657f3d393a51e (diff)
dm raid: use dm_arg_set API in constructor
- use dm_arg_set API in ctr and its callees parse_raid_params() and dev_parms() - introduce _in_range() function to check a value is in a [ min, max ] range; this is to support more callers in parsing parameters etc. in the future - correct comment on MAX_RAID_DEVICES Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-raid.c')
-rw-r--r--drivers/md/dm-raid.c145
1 files changed, 84 insertions, 61 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 6982e23681be..01aa511ebe44 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -17,7 +17,7 @@
17#include <linux/device-mapper.h> 17#include <linux/device-mapper.h>
18 18
19#define DM_MSG_PREFIX "raid" 19#define DM_MSG_PREFIX "raid"
20#define MAX_RAID_DEVICES 253 /* raid4/5/6 limit */ 20#define MAX_RAID_DEVICES 253 /* md-raid kernel limit */
21 21
22static bool devices_handle_discard_safely = false; 22static bool devices_handle_discard_safely = false;
23 23
@@ -95,6 +95,12 @@ static struct raid_type {
95 {"raid6_nc", "RAID6 (N continue)", 2, 4, 6, ALGORITHM_ROTATING_N_CONTINUE} 95 {"raid6_nc", "RAID6 (N continue)", 2, 4, 6, ALGORITHM_ROTATING_N_CONTINUE}
96}; 96};
97 97
98/* True, if @v is in inclusive range [@min, @max] */
99static bool _in_range(long v, long min, long max)
100{
101 return v >= min && v <= max;
102}
103
98static char *raid10_md_layout_to_format(int layout) 104static char *raid10_md_layout_to_format(int layout)
99{ 105{
100 /* 106 /*
@@ -135,7 +141,7 @@ static int raid10_format_to_md_layout(char *format, unsigned copies)
135 return (f << 8) | n; 141 return (f << 8) | n;
136} 142}
137 143
138static struct raid_type *get_raid_type(char *name) 144static struct raid_type *get_raid_type(const char *name)
139{ 145{
140 int i; 146 int i;
141 147
@@ -220,14 +226,20 @@ static void context_free(struct raid_set *rs)
220 * This code parses those words. If there is a failure, 226 * This code parses those words. If there is a failure,
221 * the caller must use context_free to unwind the operations. 227 * the caller must use context_free to unwind the operations.
222 */ 228 */
223static int dev_parms(struct raid_set *rs, char **argv) 229static int parse_dev_parms(struct raid_set *rs, struct dm_arg_set *as)
224{ 230{
225 int i; 231 int i;
226 int rebuild = 0; 232 int rebuild = 0;
227 int metadata_available = 0; 233 int metadata_available = 0;
228 int r = 0; 234 int r = 0;
235 const char *arg;
229 236
230 for (i = 0; i < rs->md.raid_disks; i++, argv += 2) { 237 /* Put off the number of raid devices argument to get to dev pairs */
238 arg = dm_shift_arg(as);
239 if (!arg)
240 return -EINVAL;
241
242 for (i = 0; i < rs->md.raid_disks; i++) {
231 rs->dev[i].rdev.raid_disk = i; 243 rs->dev[i].rdev.raid_disk = i;
232 244
233 rs->dev[i].meta_dev = NULL; 245 rs->dev[i].meta_dev = NULL;
@@ -240,8 +252,12 @@ static int dev_parms(struct raid_set *rs, char **argv)
240 rs->dev[i].rdev.data_offset = 0; 252 rs->dev[i].rdev.data_offset = 0;
241 rs->dev[i].rdev.mddev = &rs->md; 253 rs->dev[i].rdev.mddev = &rs->md;
242 254
243 if (strcmp(argv[0], "-")) { 255 arg = dm_shift_arg(as);
244 r = dm_get_device(rs->ti, argv[0], 256 if (!arg)
257 return -EINVAL;
258
259 if (strcmp(arg, "-")) {
260 r = dm_get_device(rs->ti, arg,
245 dm_table_get_mode(rs->ti->table), 261 dm_table_get_mode(rs->ti->table),
246 &rs->dev[i].meta_dev); 262 &rs->dev[i].meta_dev);
247 rs->ti->error = "RAID metadata device lookup failure"; 263 rs->ti->error = "RAID metadata device lookup failure";
@@ -253,7 +269,11 @@ static int dev_parms(struct raid_set *rs, char **argv)
253 return -ENOMEM; 269 return -ENOMEM;
254 } 270 }
255 271
256 if (!strcmp(argv[1], "-")) { 272 arg = dm_shift_arg(as);
273 if (!arg)
274 return -EINVAL;
275
276 if (!strcmp(arg, "-")) {
257 if (!test_bit(In_sync, &rs->dev[i].rdev.flags) && 277 if (!test_bit(In_sync, &rs->dev[i].rdev.flags) &&
258 (!rs->dev[i].rdev.recovery_offset)) { 278 (!rs->dev[i].rdev.recovery_offset)) {
259 rs->ti->error = "Drive designated for rebuild not specified"; 279 rs->ti->error = "Drive designated for rebuild not specified";
@@ -267,7 +287,7 @@ static int dev_parms(struct raid_set *rs, char **argv)
267 continue; 287 continue;
268 } 288 }
269 289
270 r = dm_get_device(rs->ti, argv[1], 290 r = dm_get_device(rs->ti, arg,
271 dm_table_get_mode(rs->ti->table), 291 dm_table_get_mode(rs->ti->table),
272 &rs->dev[i].data_dev); 292 &rs->dev[i].data_dev);
273 if (r) { 293 if (r) {
@@ -492,25 +512,30 @@ too_many:
492 * [raid10_copies <# copies>] Number of copies. (Default: 2) 512 * [raid10_copies <# copies>] Number of copies. (Default: 2)
493 * [raid10_format <near|far|offset>] Layout algorithm. (Default: near) 513 * [raid10_format <near|far|offset>] Layout algorithm. (Default: near)
494 */ 514 */
495static int parse_raid_params(struct raid_set *rs, char **argv, 515static int parse_raid_params(struct raid_set *rs, struct dm_arg_set *as,
496 unsigned num_raid_params) 516 unsigned num_raid_params)
497{ 517{
498 char *raid10_format = "near"; 518 char *raid10_format = "near";
499 unsigned raid10_copies = 2; 519 unsigned raid10_copies = 2;
500 unsigned i; 520 unsigned i;
501 unsigned long value, region_size = 0; 521 unsigned value, region_size = 0;
502 sector_t sectors_per_dev = rs->ti->len; 522 sector_t sectors_per_dev = rs->ti->len;
503 sector_t max_io_len; 523 sector_t max_io_len;
504 char *key; 524 const char *arg, *key;
525
526 arg = dm_shift_arg(as);
527 num_raid_params--; /* Account for chunk_size argument */
528
529 if (kstrtouint(arg, 10, &value) < 0) {
530 rs->ti->error = "Bad numerical argument given for chunk_size";
531 return -EINVAL;
532 }
505 533
506 /* 534 /*
507 * First, parse the in-order required arguments 535 * First, parse the in-order required arguments
508 * "chunk_size" is the only argument of this type. 536 * "chunk_size" is the only argument of this type.
509 */ 537 */
510 if ((kstrtoul(argv[0], 10, &value) < 0)) { 538 if (rs->raid_type->level == 1) {
511 rs->ti->error = "Bad chunk size";
512 return -EINVAL;
513 } else if (rs->raid_type->level == 1) {
514 if (value) 539 if (value)
515 DMERR("Ignoring chunk size parameter for RAID 1"); 540 DMERR("Ignoring chunk size parameter for RAID 1");
516 value = 0; 541 value = 0;
@@ -523,8 +548,6 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
523 } 548 }
524 549
525 rs->md.new_chunk_sectors = rs->md.chunk_sectors = value; 550 rs->md.new_chunk_sectors = rs->md.chunk_sectors = value;
526 argv++;
527 num_raid_params--;
528 551
529 /* 552 /*
530 * We set each individual device as In_sync with a completed 553 * We set each individual device as In_sync with a completed
@@ -552,12 +575,18 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
552 * Second, parse the unordered optional arguments 575 * Second, parse the unordered optional arguments
553 */ 576 */
554 for (i = 0; i < num_raid_params; i++) { 577 for (i = 0; i < num_raid_params; i++) {
555 if (!strcasecmp(argv[i], "nosync")) { 578 arg = dm_shift_arg(as);
579 if (!arg) {
580 rs->ti->error = "Not enough raid parameters given";
581 return -EINVAL;
582 }
583
584 if (!strcasecmp(arg, "nosync")) {
556 rs->md.recovery_cp = MaxSector; 585 rs->md.recovery_cp = MaxSector;
557 rs->ctr_flags |= CTR_FLAG_NOSYNC; 586 rs->ctr_flags |= CTR_FLAG_NOSYNC;
558 continue; 587 continue;
559 } 588 }
560 if (!strcasecmp(argv[i], "sync")) { 589 if (!strcasecmp(arg, "sync")) {
561 rs->md.recovery_cp = 0; 590 rs->md.recovery_cp = 0;
562 rs->ctr_flags |= CTR_FLAG_SYNC; 591 rs->ctr_flags |= CTR_FLAG_SYNC;
563 continue; 592 continue;
@@ -569,7 +598,9 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
569 return -EINVAL; 598 return -EINVAL;
570 } 599 }
571 600
572 key = argv[i++]; 601 key = arg;
602 arg = dm_shift_arg(as);
603 i++; /* Account for the argument pairs */
573 604
574 /* Parameters that take a string value are checked here. */ 605 /* Parameters that take a string value are checked here. */
575 if (!strcasecmp(key, "raid10_format")) { 606 if (!strcasecmp(key, "raid10_format")) {
@@ -577,18 +608,18 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
577 rs->ti->error = "'raid10_format' is an invalid parameter for this RAID type"; 608 rs->ti->error = "'raid10_format' is an invalid parameter for this RAID type";
578 return -EINVAL; 609 return -EINVAL;
579 } 610 }
580 if (strcmp("near", argv[i]) && 611 if (strcmp("near", arg) &&
581 strcmp("far", argv[i]) && 612 strcmp("far", arg) &&
582 strcmp("offset", argv[i])) { 613 strcmp("offset", arg)) {
583 rs->ti->error = "Invalid 'raid10_format' value given"; 614 rs->ti->error = "Invalid 'raid10_format' value given";
584 return -EINVAL; 615 return -EINVAL;
585 } 616 }
586 raid10_format = argv[i]; 617 raid10_format = (char *) arg;
587 rs->ctr_flags |= CTR_FLAG_RAID10_FORMAT; 618 rs->ctr_flags |= CTR_FLAG_RAID10_FORMAT;
588 continue; 619 continue;
589 } 620 }
590 621
591 if (kstrtoul(argv[i], 10, &value) < 0) { 622 if (kstrtouint(arg, 10, &value) < 0) {
592 rs->ti->error = "Bad numerical argument given in raid params"; 623 rs->ti->error = "Bad numerical argument given in raid params";
593 return -EINVAL; 624 return -EINVAL;
594 } 625 }
@@ -1223,61 +1254,53 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
1223{ 1254{
1224 int r; 1255 int r;
1225 struct raid_type *rt; 1256 struct raid_type *rt;
1226 unsigned long num_raid_params, num_raid_devs; 1257 unsigned num_raid_params, num_raid_devs;
1227 struct raid_set *rs = NULL; 1258 struct raid_set *rs = NULL;
1228 1259 const char *arg;
1229 /* Must have at least <raid_type> <#raid_params> */ 1260 struct dm_arg_set as = { argc, argv }, as_nrd;
1230 if (argc < 2) { 1261 struct dm_arg _args[] = {
1231 ti->error = "Too few arguments"; 1262 { 0, as.argc, "Cannot understand number of raid parameters" },
1263 { 1, 254, "Cannot understand number of raid devices parameters" }
1264 };
1265
1266 /* Must have <raid_type> */
1267 arg = dm_shift_arg(&as);
1268 if (!arg) {
1269 ti->error = "No arguments";
1232 return -EINVAL; 1270 return -EINVAL;
1233 } 1271 }
1234 1272
1235 /* raid type */ 1273 rt = get_raid_type(arg);
1236 rt = get_raid_type(argv[0]);
1237 if (!rt) { 1274 if (!rt) {
1238 ti->error = "Unrecognised raid_type"; 1275 ti->error = "Unrecognised raid_type";
1239 return -EINVAL; 1276 return -EINVAL;
1240 } 1277 }
1241 argc--;
1242 argv++;
1243
1244 /* number of RAID parameters */
1245 if (kstrtoul(argv[0], 10, &num_raid_params) < 0) {
1246 ti->error = "Cannot understand number of RAID parameters";
1247 return -EINVAL;
1248 }
1249 argc--;
1250 argv++;
1251 1278
1252 /* Skip over RAID params for now and find out # of devices */ 1279 /* Must have <#raid_params> */
1253 if (num_raid_params >= argc) { 1280 if (dm_read_arg_group(_args, &as, &num_raid_params, &ti->error))
1254 ti->error = "Arguments do not agree with counts given"; 1281 return -EINVAL;
1255 return -EINVAL;
1256 }
1257 1282
1258 if ((kstrtoul(argv[num_raid_params], 10, &num_raid_devs) < 0) || 1283 /* number of raid device tupples <meta_dev data_dev> */
1259 (num_raid_devs > MAX_RAID_DEVICES)) { 1284 as_nrd = as;
1260 ti->error = "Cannot understand number of raid devices"; 1285 dm_consume_args(&as_nrd, num_raid_params);
1261 return -EINVAL; 1286 _args[1].max = (as_nrd.argc - 1) / 2;
1262 } 1287 if (dm_read_arg(_args + 1, &as_nrd, &num_raid_devs, &ti->error))
1288 return -EINVAL;
1263 1289
1264 argc -= num_raid_params + 1; /* +1: we already have num_raid_devs */ 1290 if (!_in_range(num_raid_devs, 1, MAX_RAID_DEVICES)) {
1265 if (argc != (num_raid_devs * 2)) { 1291 ti->error = "Invalid number of supplied raid devices";
1266 ti->error = "Supplied RAID devices does not match the count given"; 1292 return -EINVAL;
1267 return -EINVAL;
1268 } 1293 }
1269 1294
1270 rs = context_alloc(ti, rt, (unsigned)num_raid_devs); 1295 rs = context_alloc(ti, rt, num_raid_devs);
1271 if (IS_ERR(rs)) 1296 if (IS_ERR(rs))
1272 return PTR_ERR(rs); 1297 return PTR_ERR(rs);
1273 1298
1274 r = parse_raid_params(rs, argv, (unsigned)num_raid_params); 1299 r = parse_raid_params(rs, &as, num_raid_params);
1275 if (r) 1300 if (r)
1276 goto bad; 1301 goto bad;
1277 1302
1278 argv += num_raid_params + 1; 1303 r = parse_dev_parms(rs, &as);
1279
1280 r = dev_parms(rs, argv);
1281 if (r) 1304 if (r)
1282 goto bad; 1305 goto bad;
1283 1306