diff options
Diffstat (limited to 'drivers/md/dm-raid.c')
-rw-r--r-- | drivers/md/dm-raid.c | 225 |
1 files changed, 130 insertions, 95 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 88e4c7f24986..2daa67793511 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010-2011 Neil Brown | 2 | * Copyright (C) 2010-2011 Neil Brown |
3 | * Copyright (C) 2010-2014 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This file is released under the GPL. | 5 | * This file is released under the GPL. |
6 | */ | 6 | */ |
@@ -17,6 +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 | 21 | ||
21 | static bool devices_handle_discard_safely = false; | 22 | static bool devices_handle_discard_safely = false; |
22 | 23 | ||
@@ -45,25 +46,25 @@ struct raid_dev { | |||
45 | }; | 46 | }; |
46 | 47 | ||
47 | /* | 48 | /* |
48 | * Flags for rs->print_flags field. | 49 | * Flags for rs->ctr_flags field. |
49 | */ | 50 | */ |
50 | #define DMPF_SYNC 0x1 | 51 | #define CTR_FLAG_SYNC 0x1 |
51 | #define DMPF_NOSYNC 0x2 | 52 | #define CTR_FLAG_NOSYNC 0x2 |
52 | #define DMPF_REBUILD 0x4 | 53 | #define CTR_FLAG_REBUILD 0x4 |
53 | #define DMPF_DAEMON_SLEEP 0x8 | 54 | #define CTR_FLAG_DAEMON_SLEEP 0x8 |
54 | #define DMPF_MIN_RECOVERY_RATE 0x10 | 55 | #define CTR_FLAG_MIN_RECOVERY_RATE 0x10 |
55 | #define DMPF_MAX_RECOVERY_RATE 0x20 | 56 | #define CTR_FLAG_MAX_RECOVERY_RATE 0x20 |
56 | #define DMPF_MAX_WRITE_BEHIND 0x40 | 57 | #define CTR_FLAG_MAX_WRITE_BEHIND 0x40 |
57 | #define DMPF_STRIPE_CACHE 0x80 | 58 | #define CTR_FLAG_STRIPE_CACHE 0x80 |
58 | #define DMPF_REGION_SIZE 0x100 | 59 | #define CTR_FLAG_REGION_SIZE 0x100 |
59 | #define DMPF_RAID10_COPIES 0x200 | 60 | #define CTR_FLAG_RAID10_COPIES 0x200 |
60 | #define DMPF_RAID10_FORMAT 0x400 | 61 | #define CTR_FLAG_RAID10_FORMAT 0x400 |
61 | 62 | ||
62 | struct raid_set { | 63 | struct raid_set { |
63 | struct dm_target *ti; | 64 | struct dm_target *ti; |
64 | 65 | ||
65 | uint32_t bitmap_loaded; | 66 | uint32_t bitmap_loaded; |
66 | uint32_t print_flags; | 67 | uint32_t ctr_flags; |
67 | 68 | ||
68 | struct mddev md; | 69 | struct mddev md; |
69 | struct raid_type *raid_type; | 70 | struct raid_type *raid_type; |
@@ -81,6 +82,7 @@ static struct raid_type { | |||
81 | const unsigned level; /* RAID level. */ | 82 | const unsigned level; /* RAID level. */ |
82 | const unsigned algorithm; /* RAID algorithm. */ | 83 | const unsigned algorithm; /* RAID algorithm. */ |
83 | } raid_types[] = { | 84 | } raid_types[] = { |
85 | {"raid0", "RAID0 (striping)", 0, 2, 0, 0 /* NONE */}, | ||
84 | {"raid1", "RAID1 (mirroring)", 0, 2, 1, 0 /* NONE */}, | 86 | {"raid1", "RAID1 (mirroring)", 0, 2, 1, 0 /* NONE */}, |
85 | {"raid10", "RAID10 (striped mirrors)", 0, 2, 10, UINT_MAX /* Varies */}, | 87 | {"raid10", "RAID10 (striped mirrors)", 0, 2, 10, UINT_MAX /* Varies */}, |
86 | {"raid4", "RAID4 (dedicated parity disk)", 1, 2, 5, ALGORITHM_PARITY_0}, | 88 | {"raid4", "RAID4 (dedicated parity disk)", 1, 2, 5, ALGORITHM_PARITY_0}, |
@@ -119,15 +121,15 @@ static int raid10_format_to_md_layout(char *format, unsigned copies) | |||
119 | { | 121 | { |
120 | unsigned n = 1, f = 1; | 122 | unsigned n = 1, f = 1; |
121 | 123 | ||
122 | if (!strcmp("near", format)) | 124 | if (!strcasecmp("near", format)) |
123 | n = copies; | 125 | n = copies; |
124 | else | 126 | else |
125 | f = copies; | 127 | f = copies; |
126 | 128 | ||
127 | if (!strcmp("offset", format)) | 129 | if (!strcasecmp("offset", format)) |
128 | return 0x30000 | (f << 8) | n; | 130 | return 0x30000 | (f << 8) | n; |
129 | 131 | ||
130 | if (!strcmp("far", format)) | 132 | if (!strcasecmp("far", format)) |
131 | return 0x20000 | (f << 8) | n; | 133 | return 0x20000 | (f << 8) | n; |
132 | 134 | ||
133 | return (f << 8) | n; | 135 | return (f << 8) | n; |
@@ -477,8 +479,6 @@ too_many: | |||
477 | * will form the "stripe" | 479 | * will form the "stripe" |
478 | * [[no]sync] Force or prevent recovery of the | 480 | * [[no]sync] Force or prevent recovery of the |
479 | * entire array | 481 | * entire array |
480 | * [devices_handle_discard_safely] Allow discards on RAID4/5/6; useful if RAID | ||
481 | * member device(s) properly support TRIM/UNMAP | ||
482 | * [rebuild <idx>] Rebuild the drive indicated by the index | 482 | * [rebuild <idx>] Rebuild the drive indicated by the index |
483 | * [daemon_sleep <ms>] Time between bitmap daemon work to | 483 | * [daemon_sleep <ms>] Time between bitmap daemon work to |
484 | * clear bits | 484 | * clear bits |
@@ -555,12 +555,12 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
555 | for (i = 0; i < num_raid_params; i++) { | 555 | for (i = 0; i < num_raid_params; i++) { |
556 | if (!strcasecmp(argv[i], "nosync")) { | 556 | if (!strcasecmp(argv[i], "nosync")) { |
557 | rs->md.recovery_cp = MaxSector; | 557 | rs->md.recovery_cp = MaxSector; |
558 | rs->print_flags |= DMPF_NOSYNC; | 558 | rs->ctr_flags |= CTR_FLAG_NOSYNC; |
559 | continue; | 559 | continue; |
560 | } | 560 | } |
561 | if (!strcasecmp(argv[i], "sync")) { | 561 | if (!strcasecmp(argv[i], "sync")) { |
562 | rs->md.recovery_cp = 0; | 562 | rs->md.recovery_cp = 0; |
563 | rs->print_flags |= DMPF_SYNC; | 563 | rs->ctr_flags |= CTR_FLAG_SYNC; |
564 | continue; | 564 | continue; |
565 | } | 565 | } |
566 | 566 | ||
@@ -585,7 +585,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
585 | return -EINVAL; | 585 | return -EINVAL; |
586 | } | 586 | } |
587 | raid10_format = argv[i]; | 587 | raid10_format = argv[i]; |
588 | rs->print_flags |= DMPF_RAID10_FORMAT; | 588 | rs->ctr_flags |= CTR_FLAG_RAID10_FORMAT; |
589 | continue; | 589 | continue; |
590 | } | 590 | } |
591 | 591 | ||
@@ -602,7 +602,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
602 | } | 602 | } |
603 | clear_bit(In_sync, &rs->dev[value].rdev.flags); | 603 | clear_bit(In_sync, &rs->dev[value].rdev.flags); |
604 | rs->dev[value].rdev.recovery_offset = 0; | 604 | rs->dev[value].rdev.recovery_offset = 0; |
605 | rs->print_flags |= DMPF_REBUILD; | 605 | rs->ctr_flags |= CTR_FLAG_REBUILD; |
606 | } else if (!strcasecmp(key, "write_mostly")) { | 606 | } else if (!strcasecmp(key, "write_mostly")) { |
607 | if (rs->raid_type->level != 1) { | 607 | if (rs->raid_type->level != 1) { |
608 | rs->ti->error = "write_mostly option is only valid for RAID1"; | 608 | rs->ti->error = "write_mostly option is only valid for RAID1"; |
@@ -618,7 +618,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
618 | rs->ti->error = "max_write_behind option is only valid for RAID1"; | 618 | rs->ti->error = "max_write_behind option is only valid for RAID1"; |
619 | return -EINVAL; | 619 | return -EINVAL; |
620 | } | 620 | } |
621 | rs->print_flags |= DMPF_MAX_WRITE_BEHIND; | 621 | rs->ctr_flags |= CTR_FLAG_MAX_WRITE_BEHIND; |
622 | 622 | ||
623 | /* | 623 | /* |
624 | * In device-mapper, we specify things in sectors, but | 624 | * In device-mapper, we specify things in sectors, but |
@@ -631,14 +631,14 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
631 | } | 631 | } |
632 | rs->md.bitmap_info.max_write_behind = value; | 632 | rs->md.bitmap_info.max_write_behind = value; |
633 | } else if (!strcasecmp(key, "daemon_sleep")) { | 633 | } else if (!strcasecmp(key, "daemon_sleep")) { |
634 | rs->print_flags |= DMPF_DAEMON_SLEEP; | 634 | rs->ctr_flags |= CTR_FLAG_DAEMON_SLEEP; |
635 | if (!value || (value > MAX_SCHEDULE_TIMEOUT)) { | 635 | if (!value || (value > MAX_SCHEDULE_TIMEOUT)) { |
636 | rs->ti->error = "daemon sleep period out of range"; | 636 | rs->ti->error = "daemon sleep period out of range"; |
637 | return -EINVAL; | 637 | return -EINVAL; |
638 | } | 638 | } |
639 | rs->md.bitmap_info.daemon_sleep = value; | 639 | rs->md.bitmap_info.daemon_sleep = value; |
640 | } else if (!strcasecmp(key, "stripe_cache")) { | 640 | } else if (!strcasecmp(key, "stripe_cache")) { |
641 | rs->print_flags |= DMPF_STRIPE_CACHE; | 641 | rs->ctr_flags |= CTR_FLAG_STRIPE_CACHE; |
642 | 642 | ||
643 | /* | 643 | /* |
644 | * In device-mapper, we specify things in sectors, but | 644 | * In device-mapper, we specify things in sectors, but |
@@ -656,21 +656,21 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
656 | return -EINVAL; | 656 | return -EINVAL; |
657 | } | 657 | } |
658 | } else if (!strcasecmp(key, "min_recovery_rate")) { | 658 | } else if (!strcasecmp(key, "min_recovery_rate")) { |
659 | rs->print_flags |= DMPF_MIN_RECOVERY_RATE; | 659 | rs->ctr_flags |= CTR_FLAG_MIN_RECOVERY_RATE; |
660 | if (value > INT_MAX) { | 660 | if (value > INT_MAX) { |
661 | rs->ti->error = "min_recovery_rate out of range"; | 661 | rs->ti->error = "min_recovery_rate out of range"; |
662 | return -EINVAL; | 662 | return -EINVAL; |
663 | } | 663 | } |
664 | rs->md.sync_speed_min = (int)value; | 664 | rs->md.sync_speed_min = (int)value; |
665 | } else if (!strcasecmp(key, "max_recovery_rate")) { | 665 | } else if (!strcasecmp(key, "max_recovery_rate")) { |
666 | rs->print_flags |= DMPF_MAX_RECOVERY_RATE; | 666 | rs->ctr_flags |= CTR_FLAG_MAX_RECOVERY_RATE; |
667 | if (value > INT_MAX) { | 667 | if (value > INT_MAX) { |
668 | rs->ti->error = "max_recovery_rate out of range"; | 668 | rs->ti->error = "max_recovery_rate out of range"; |
669 | return -EINVAL; | 669 | return -EINVAL; |
670 | } | 670 | } |
671 | rs->md.sync_speed_max = (int)value; | 671 | rs->md.sync_speed_max = (int)value; |
672 | } else if (!strcasecmp(key, "region_size")) { | 672 | } else if (!strcasecmp(key, "region_size")) { |
673 | rs->print_flags |= DMPF_REGION_SIZE; | 673 | rs->ctr_flags |= CTR_FLAG_REGION_SIZE; |
674 | region_size = value; | 674 | region_size = value; |
675 | } else if (!strcasecmp(key, "raid10_copies") && | 675 | } else if (!strcasecmp(key, "raid10_copies") && |
676 | (rs->raid_type->level == 10)) { | 676 | (rs->raid_type->level == 10)) { |
@@ -678,7 +678,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
678 | rs->ti->error = "Bad value for 'raid10_copies'"; | 678 | rs->ti->error = "Bad value for 'raid10_copies'"; |
679 | return -EINVAL; | 679 | return -EINVAL; |
680 | } | 680 | } |
681 | rs->print_flags |= DMPF_RAID10_COPIES; | 681 | rs->ctr_flags |= CTR_FLAG_RAID10_COPIES; |
682 | raid10_copies = value; | 682 | raid10_copies = value; |
683 | } else { | 683 | } else { |
684 | DMERR("Unable to parse RAID parameter: %s", key); | 684 | DMERR("Unable to parse RAID parameter: %s", key); |
@@ -720,7 +720,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
720 | rs->md.layout = raid10_format_to_md_layout(raid10_format, | 720 | rs->md.layout = raid10_format_to_md_layout(raid10_format, |
721 | raid10_copies); | 721 | raid10_copies); |
722 | rs->md.new_layout = rs->md.layout; | 722 | rs->md.new_layout = rs->md.layout; |
723 | } else if ((rs->raid_type->level > 1) && | 723 | } else if ((!rs->raid_type->level || rs->raid_type->level > 1) && |
724 | sector_div(sectors_per_dev, | 724 | sector_div(sectors_per_dev, |
725 | (rs->md.raid_disks - rs->raid_type->parity_devs))) { | 725 | (rs->md.raid_disks - rs->raid_type->parity_devs))) { |
726 | rs->ti->error = "Target length not divisible by number of data devices"; | 726 | rs->ti->error = "Target length not divisible by number of data devices"; |
@@ -947,7 +947,7 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev) | |||
947 | return -EINVAL; | 947 | return -EINVAL; |
948 | } | 948 | } |
949 | 949 | ||
950 | if (!(rs->print_flags & (DMPF_SYNC | DMPF_NOSYNC))) | 950 | if (!(rs->ctr_flags & (CTR_FLAG_SYNC | CTR_FLAG_NOSYNC))) |
951 | mddev->recovery_cp = le64_to_cpu(sb->array_resync_offset); | 951 | mddev->recovery_cp = le64_to_cpu(sb->array_resync_offset); |
952 | 952 | ||
953 | /* | 953 | /* |
@@ -1026,8 +1026,9 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev) | |||
1026 | return 0; | 1026 | return 0; |
1027 | } | 1027 | } |
1028 | 1028 | ||
1029 | static int super_validate(struct mddev *mddev, struct md_rdev *rdev) | 1029 | static int super_validate(struct raid_set *rs, struct md_rdev *rdev) |
1030 | { | 1030 | { |
1031 | struct mddev *mddev = &rs->md; | ||
1031 | struct dm_raid_superblock *sb = page_address(rdev->sb_page); | 1032 | struct dm_raid_superblock *sb = page_address(rdev->sb_page); |
1032 | 1033 | ||
1033 | /* | 1034 | /* |
@@ -1037,8 +1038,10 @@ static int super_validate(struct mddev *mddev, struct md_rdev *rdev) | |||
1037 | if (!mddev->events && super_init_validation(mddev, rdev)) | 1038 | if (!mddev->events && super_init_validation(mddev, rdev)) |
1038 | return -EINVAL; | 1039 | return -EINVAL; |
1039 | 1040 | ||
1040 | mddev->bitmap_info.offset = 4096 >> 9; /* Enable bitmap creation */ | 1041 | /* Enable bitmap creation for RAID levels != 0 */ |
1041 | rdev->mddev->bitmap_info.default_offset = 4096 >> 9; | 1042 | mddev->bitmap_info.offset = (rs->raid_type->level) ? to_sector(4096) : 0; |
1043 | rdev->mddev->bitmap_info.default_offset = mddev->bitmap_info.offset; | ||
1044 | |||
1042 | if (!test_bit(FirstUse, &rdev->flags)) { | 1045 | if (!test_bit(FirstUse, &rdev->flags)) { |
1043 | rdev->recovery_offset = le64_to_cpu(sb->disk_recovery_offset); | 1046 | rdev->recovery_offset = le64_to_cpu(sb->disk_recovery_offset); |
1044 | if (rdev->recovery_offset != MaxSector) | 1047 | if (rdev->recovery_offset != MaxSector) |
@@ -1073,7 +1076,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) | |||
1073 | freshest = NULL; | 1076 | freshest = NULL; |
1074 | rdev_for_each_safe(rdev, tmp, mddev) { | 1077 | rdev_for_each_safe(rdev, tmp, mddev) { |
1075 | /* | 1078 | /* |
1076 | * Skipping super_load due to DMPF_SYNC will cause | 1079 | * Skipping super_load due to CTR_FLAG_SYNC will cause |
1077 | * the array to undergo initialization again as | 1080 | * the array to undergo initialization again as |
1078 | * though it were new. This is the intended effect | 1081 | * though it were new. This is the intended effect |
1079 | * of the "sync" directive. | 1082 | * of the "sync" directive. |
@@ -1082,7 +1085,9 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) | |||
1082 | * that the "sync" directive is disallowed during the | 1085 | * that the "sync" directive is disallowed during the |
1083 | * reshape. | 1086 | * reshape. |
1084 | */ | 1087 | */ |
1085 | if (rs->print_flags & DMPF_SYNC) | 1088 | rdev->sectors = to_sector(i_size_read(rdev->bdev->bd_inode)); |
1089 | |||
1090 | if (rs->ctr_flags & CTR_FLAG_SYNC) | ||
1086 | continue; | 1091 | continue; |
1087 | 1092 | ||
1088 | if (!rdev->meta_bdev) | 1093 | if (!rdev->meta_bdev) |
@@ -1140,11 +1145,11 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) | |||
1140 | * validation for the remaining devices. | 1145 | * validation for the remaining devices. |
1141 | */ | 1146 | */ |
1142 | ti->error = "Unable to assemble array: Invalid superblocks"; | 1147 | ti->error = "Unable to assemble array: Invalid superblocks"; |
1143 | if (super_validate(mddev, freshest)) | 1148 | if (super_validate(rs, freshest)) |
1144 | return -EINVAL; | 1149 | return -EINVAL; |
1145 | 1150 | ||
1146 | rdev_for_each(rdev, mddev) | 1151 | rdev_for_each(rdev, mddev) |
1147 | if ((rdev != freshest) && super_validate(mddev, rdev)) | 1152 | if ((rdev != freshest) && super_validate(rs, rdev)) |
1148 | return -EINVAL; | 1153 | return -EINVAL; |
1149 | 1154 | ||
1150 | return 0; | 1155 | return 0; |
@@ -1243,7 +1248,7 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
1243 | } | 1248 | } |
1244 | 1249 | ||
1245 | if ((kstrtoul(argv[num_raid_params], 10, &num_raid_devs) < 0) || | 1250 | if ((kstrtoul(argv[num_raid_params], 10, &num_raid_devs) < 0) || |
1246 | (num_raid_devs >= INT_MAX)) { | 1251 | (num_raid_devs > MAX_RAID_DEVICES)) { |
1247 | ti->error = "Cannot understand number of raid devices"; | 1252 | ti->error = "Cannot understand number of raid devices"; |
1248 | return -EINVAL; | 1253 | return -EINVAL; |
1249 | } | 1254 | } |
@@ -1282,10 +1287,11 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
1282 | */ | 1287 | */ |
1283 | configure_discard_support(ti, rs); | 1288 | configure_discard_support(ti, rs); |
1284 | 1289 | ||
1285 | mutex_lock(&rs->md.reconfig_mutex); | 1290 | /* Has to be held on running the array */ |
1291 | mddev_lock_nointr(&rs->md); | ||
1286 | ret = md_run(&rs->md); | 1292 | ret = md_run(&rs->md); |
1287 | rs->md.in_sync = 0; /* Assume already marked dirty */ | 1293 | rs->md.in_sync = 0; /* Assume already marked dirty */ |
1288 | mutex_unlock(&rs->md.reconfig_mutex); | 1294 | mddev_unlock(&rs->md); |
1289 | 1295 | ||
1290 | if (ret) { | 1296 | if (ret) { |
1291 | ti->error = "Fail to run raid array"; | 1297 | ti->error = "Fail to run raid array"; |
@@ -1368,34 +1374,40 @@ static void raid_status(struct dm_target *ti, status_type_t type, | |||
1368 | case STATUSTYPE_INFO: | 1374 | case STATUSTYPE_INFO: |
1369 | DMEMIT("%s %d ", rs->raid_type->name, rs->md.raid_disks); | 1375 | DMEMIT("%s %d ", rs->raid_type->name, rs->md.raid_disks); |
1370 | 1376 | ||
1371 | if (test_bit(MD_RECOVERY_RUNNING, &rs->md.recovery)) | 1377 | if (rs->raid_type->level) { |
1372 | sync = rs->md.curr_resync_completed; | 1378 | if (test_bit(MD_RECOVERY_RUNNING, &rs->md.recovery)) |
1373 | else | 1379 | sync = rs->md.curr_resync_completed; |
1374 | sync = rs->md.recovery_cp; | 1380 | else |
1375 | 1381 | sync = rs->md.recovery_cp; | |
1376 | if (sync >= rs->md.resync_max_sectors) { | 1382 | |
1377 | /* | 1383 | if (sync >= rs->md.resync_max_sectors) { |
1378 | * Sync complete. | 1384 | /* |
1379 | */ | 1385 | * Sync complete. |
1386 | */ | ||
1387 | array_in_sync = 1; | ||
1388 | sync = rs->md.resync_max_sectors; | ||
1389 | } else if (test_bit(MD_RECOVERY_REQUESTED, &rs->md.recovery)) { | ||
1390 | /* | ||
1391 | * If "check" or "repair" is occurring, the array has | ||
1392 | * undergone and initial sync and the health characters | ||
1393 | * should not be 'a' anymore. | ||
1394 | */ | ||
1395 | array_in_sync = 1; | ||
1396 | } else { | ||
1397 | /* | ||
1398 | * The array may be doing an initial sync, or it may | ||
1399 | * be rebuilding individual components. If all the | ||
1400 | * devices are In_sync, then it is the array that is | ||
1401 | * being initialized. | ||
1402 | */ | ||
1403 | for (i = 0; i < rs->md.raid_disks; i++) | ||
1404 | if (!test_bit(In_sync, &rs->dev[i].rdev.flags)) | ||
1405 | array_in_sync = 1; | ||
1406 | } | ||
1407 | } else { | ||
1408 | /* RAID0 */ | ||
1380 | array_in_sync = 1; | 1409 | array_in_sync = 1; |
1381 | sync = rs->md.resync_max_sectors; | 1410 | sync = rs->md.resync_max_sectors; |
1382 | } else if (test_bit(MD_RECOVERY_REQUESTED, &rs->md.recovery)) { | ||
1383 | /* | ||
1384 | * If "check" or "repair" is occurring, the array has | ||
1385 | * undergone and initial sync and the health characters | ||
1386 | * should not be 'a' anymore. | ||
1387 | */ | ||
1388 | array_in_sync = 1; | ||
1389 | } else { | ||
1390 | /* | ||
1391 | * The array may be doing an initial sync, or it may | ||
1392 | * be rebuilding individual components. If all the | ||
1393 | * devices are In_sync, then it is the array that is | ||
1394 | * being initialized. | ||
1395 | */ | ||
1396 | for (i = 0; i < rs->md.raid_disks; i++) | ||
1397 | if (!test_bit(In_sync, &rs->dev[i].rdev.flags)) | ||
1398 | array_in_sync = 1; | ||
1399 | } | 1411 | } |
1400 | 1412 | ||
1401 | /* | 1413 | /* |
@@ -1446,7 +1458,7 @@ static void raid_status(struct dm_target *ti, status_type_t type, | |||
1446 | case STATUSTYPE_TABLE: | 1458 | case STATUSTYPE_TABLE: |
1447 | /* The string you would use to construct this array */ | 1459 | /* The string you would use to construct this array */ |
1448 | for (i = 0; i < rs->md.raid_disks; i++) { | 1460 | for (i = 0; i < rs->md.raid_disks; i++) { |
1449 | if ((rs->print_flags & DMPF_REBUILD) && | 1461 | if ((rs->ctr_flags & CTR_FLAG_REBUILD) && |
1450 | rs->dev[i].data_dev && | 1462 | rs->dev[i].data_dev && |
1451 | !test_bit(In_sync, &rs->dev[i].rdev.flags)) | 1463 | !test_bit(In_sync, &rs->dev[i].rdev.flags)) |
1452 | raid_param_cnt += 2; /* for rebuilds */ | 1464 | raid_param_cnt += 2; /* for rebuilds */ |
@@ -1455,33 +1467,33 @@ static void raid_status(struct dm_target *ti, status_type_t type, | |||
1455 | raid_param_cnt += 2; | 1467 | raid_param_cnt += 2; |
1456 | } | 1468 | } |
1457 | 1469 | ||
1458 | raid_param_cnt += (hweight32(rs->print_flags & ~DMPF_REBUILD) * 2); | 1470 | raid_param_cnt += (hweight32(rs->ctr_flags & ~CTR_FLAG_REBUILD) * 2); |
1459 | if (rs->print_flags & (DMPF_SYNC | DMPF_NOSYNC)) | 1471 | if (rs->ctr_flags & (CTR_FLAG_SYNC | CTR_FLAG_NOSYNC)) |
1460 | raid_param_cnt--; | 1472 | raid_param_cnt--; |
1461 | 1473 | ||
1462 | DMEMIT("%s %u %u", rs->raid_type->name, | 1474 | DMEMIT("%s %u %u", rs->raid_type->name, |
1463 | raid_param_cnt, rs->md.chunk_sectors); | 1475 | raid_param_cnt, rs->md.chunk_sectors); |
1464 | 1476 | ||
1465 | if ((rs->print_flags & DMPF_SYNC) && | 1477 | if ((rs->ctr_flags & CTR_FLAG_SYNC) && |
1466 | (rs->md.recovery_cp == MaxSector)) | 1478 | (rs->md.recovery_cp == MaxSector)) |
1467 | DMEMIT(" sync"); | 1479 | DMEMIT(" sync"); |
1468 | if (rs->print_flags & DMPF_NOSYNC) | 1480 | if (rs->ctr_flags & CTR_FLAG_NOSYNC) |
1469 | DMEMIT(" nosync"); | 1481 | DMEMIT(" nosync"); |
1470 | 1482 | ||
1471 | for (i = 0; i < rs->md.raid_disks; i++) | 1483 | for (i = 0; i < rs->md.raid_disks; i++) |
1472 | if ((rs->print_flags & DMPF_REBUILD) && | 1484 | if ((rs->ctr_flags & CTR_FLAG_REBUILD) && |
1473 | rs->dev[i].data_dev && | 1485 | rs->dev[i].data_dev && |
1474 | !test_bit(In_sync, &rs->dev[i].rdev.flags)) | 1486 | !test_bit(In_sync, &rs->dev[i].rdev.flags)) |
1475 | DMEMIT(" rebuild %u", i); | 1487 | DMEMIT(" rebuild %u", i); |
1476 | 1488 | ||
1477 | if (rs->print_flags & DMPF_DAEMON_SLEEP) | 1489 | if (rs->ctr_flags & CTR_FLAG_DAEMON_SLEEP) |
1478 | DMEMIT(" daemon_sleep %lu", | 1490 | DMEMIT(" daemon_sleep %lu", |
1479 | rs->md.bitmap_info.daemon_sleep); | 1491 | rs->md.bitmap_info.daemon_sleep); |
1480 | 1492 | ||
1481 | if (rs->print_flags & DMPF_MIN_RECOVERY_RATE) | 1493 | if (rs->ctr_flags & CTR_FLAG_MIN_RECOVERY_RATE) |
1482 | DMEMIT(" min_recovery_rate %d", rs->md.sync_speed_min); | 1494 | DMEMIT(" min_recovery_rate %d", rs->md.sync_speed_min); |
1483 | 1495 | ||
1484 | if (rs->print_flags & DMPF_MAX_RECOVERY_RATE) | 1496 | if (rs->ctr_flags & CTR_FLAG_MAX_RECOVERY_RATE) |
1485 | DMEMIT(" max_recovery_rate %d", rs->md.sync_speed_max); | 1497 | DMEMIT(" max_recovery_rate %d", rs->md.sync_speed_max); |
1486 | 1498 | ||
1487 | for (i = 0; i < rs->md.raid_disks; i++) | 1499 | for (i = 0; i < rs->md.raid_disks; i++) |
@@ -1489,11 +1501,11 @@ static void raid_status(struct dm_target *ti, status_type_t type, | |||
1489 | test_bit(WriteMostly, &rs->dev[i].rdev.flags)) | 1501 | test_bit(WriteMostly, &rs->dev[i].rdev.flags)) |
1490 | DMEMIT(" write_mostly %u", i); | 1502 | DMEMIT(" write_mostly %u", i); |
1491 | 1503 | ||
1492 | if (rs->print_flags & DMPF_MAX_WRITE_BEHIND) | 1504 | if (rs->ctr_flags & CTR_FLAG_MAX_WRITE_BEHIND) |
1493 | DMEMIT(" max_write_behind %lu", | 1505 | DMEMIT(" max_write_behind %lu", |
1494 | rs->md.bitmap_info.max_write_behind); | 1506 | rs->md.bitmap_info.max_write_behind); |
1495 | 1507 | ||
1496 | if (rs->print_flags & DMPF_STRIPE_CACHE) { | 1508 | if (rs->ctr_flags & CTR_FLAG_STRIPE_CACHE) { |
1497 | struct r5conf *conf = rs->md.private; | 1509 | struct r5conf *conf = rs->md.private; |
1498 | 1510 | ||
1499 | /* convert from kiB to sectors */ | 1511 | /* convert from kiB to sectors */ |
@@ -1501,15 +1513,15 @@ static void raid_status(struct dm_target *ti, status_type_t type, | |||
1501 | conf ? conf->max_nr_stripes * 2 : 0); | 1513 | conf ? conf->max_nr_stripes * 2 : 0); |
1502 | } | 1514 | } |
1503 | 1515 | ||
1504 | if (rs->print_flags & DMPF_REGION_SIZE) | 1516 | if (rs->ctr_flags & CTR_FLAG_REGION_SIZE) |
1505 | DMEMIT(" region_size %lu", | 1517 | DMEMIT(" region_size %lu", |
1506 | rs->md.bitmap_info.chunksize >> 9); | 1518 | rs->md.bitmap_info.chunksize >> 9); |
1507 | 1519 | ||
1508 | if (rs->print_flags & DMPF_RAID10_COPIES) | 1520 | if (rs->ctr_flags & CTR_FLAG_RAID10_COPIES) |
1509 | DMEMIT(" raid10_copies %u", | 1521 | DMEMIT(" raid10_copies %u", |
1510 | raid10_md_layout_to_copies(rs->md.layout)); | 1522 | raid10_md_layout_to_copies(rs->md.layout)); |
1511 | 1523 | ||
1512 | if (rs->print_flags & DMPF_RAID10_FORMAT) | 1524 | if (rs->ctr_flags & CTR_FLAG_RAID10_FORMAT) |
1513 | DMEMIT(" raid10_format %s", | 1525 | DMEMIT(" raid10_format %s", |
1514 | raid10_md_layout_to_format(rs->md.layout)); | 1526 | raid10_md_layout_to_format(rs->md.layout)); |
1515 | 1527 | ||
@@ -1684,26 +1696,48 @@ static void raid_resume(struct dm_target *ti) | |||
1684 | { | 1696 | { |
1685 | struct raid_set *rs = ti->private; | 1697 | struct raid_set *rs = ti->private; |
1686 | 1698 | ||
1687 | set_bit(MD_CHANGE_DEVS, &rs->md.flags); | 1699 | if (rs->raid_type->level) { |
1688 | if (!rs->bitmap_loaded) { | 1700 | set_bit(MD_CHANGE_DEVS, &rs->md.flags); |
1689 | bitmap_load(&rs->md); | 1701 | |
1690 | rs->bitmap_loaded = 1; | 1702 | if (!rs->bitmap_loaded) { |
1691 | } else { | 1703 | bitmap_load(&rs->md); |
1692 | /* | 1704 | rs->bitmap_loaded = 1; |
1693 | * A secondary resume while the device is active. | 1705 | } else { |
1694 | * Take this opportunity to check whether any failed | 1706 | /* |
1695 | * devices are reachable again. | 1707 | * A secondary resume while the device is active. |
1696 | */ | 1708 | * Take this opportunity to check whether any failed |
1697 | attempt_restore_of_faulty_devices(rs); | 1709 | * devices are reachable again. |
1710 | */ | ||
1711 | attempt_restore_of_faulty_devices(rs); | ||
1712 | } | ||
1713 | |||
1714 | clear_bit(MD_RECOVERY_FROZEN, &rs->md.recovery); | ||
1698 | } | 1715 | } |
1699 | 1716 | ||
1700 | clear_bit(MD_RECOVERY_FROZEN, &rs->md.recovery); | ||
1701 | mddev_resume(&rs->md); | 1717 | mddev_resume(&rs->md); |
1702 | } | 1718 | } |
1703 | 1719 | ||
1720 | static int raid_merge(struct dm_target *ti, struct bvec_merge_data *bvm, | ||
1721 | struct bio_vec *biovec, int max_size) | ||
1722 | { | ||
1723 | struct raid_set *rs = ti->private; | ||
1724 | struct md_personality *pers = rs->md.pers; | ||
1725 | |||
1726 | if (pers && pers->mergeable_bvec) | ||
1727 | return min(max_size, pers->mergeable_bvec(&rs->md, bvm, biovec)); | ||
1728 | |||
1729 | /* | ||
1730 | * In case we can't request the personality because | ||
1731 | * the raid set is not running yet | ||
1732 | * | ||
1733 | * -> return safe minimum | ||
1734 | */ | ||
1735 | return rs->md.chunk_sectors; | ||
1736 | } | ||
1737 | |||
1704 | static struct target_type raid_target = { | 1738 | static struct target_type raid_target = { |
1705 | .name = "raid", | 1739 | .name = "raid", |
1706 | .version = {1, 6, 0}, | 1740 | .version = {1, 7, 0}, |
1707 | .module = THIS_MODULE, | 1741 | .module = THIS_MODULE, |
1708 | .ctr = raid_ctr, | 1742 | .ctr = raid_ctr, |
1709 | .dtr = raid_dtr, | 1743 | .dtr = raid_dtr, |
@@ -1715,6 +1749,7 @@ static struct target_type raid_target = { | |||
1715 | .presuspend = raid_presuspend, | 1749 | .presuspend = raid_presuspend, |
1716 | .postsuspend = raid_postsuspend, | 1750 | .postsuspend = raid_postsuspend, |
1717 | .resume = raid_resume, | 1751 | .resume = raid_resume, |
1752 | .merge = raid_merge, | ||
1718 | }; | 1753 | }; |
1719 | 1754 | ||
1720 | static int __init dm_raid_init(void) | 1755 | static int __init dm_raid_init(void) |