* Choose a reasonable default. All figures in sectors.
*/
if (min_region_size > (1 << 13)) {
+ /* If not a power of 2, make it the next power of 2 */
+ if (min_region_size & (min_region_size - 1))
+ region_size = 1 << fls(region_size);
DMINFO("Choosing default region size of %lu sectors",
region_size);
- region_size = min_region_size;
} else {
DMINFO("Choosing default region size of 4MiB");
region_size = 1 << 13; /* sectors */
static int validate_rebuild_devices(struct raid_set *rs)
{
unsigned i, rebuild_cnt = 0;
+ unsigned rebuilds_per_group, copies, d;
if (!(rs->print_flags & DMPF_REBUILD))
return 0;
goto too_many;
break;
case 10:
+ copies = raid10_md_layout_to_copies(rs->md.layout);
+ if (rebuild_cnt < copies)
+ break;
+
+ /*
+ * It is possible to have a higher rebuild count for RAID10,
+ * as long as the failed devices occur in different mirror
+ * groups (i.e. different stripes).
+ *
+ * Right now, we only allow for "near" copies. When other
+ * formats are added, we will have to check those too.
+ *
+ * When checking "near" format, make sure no adjacent devices
+ * have failed beyond what can be handled. In addition to the
+ * simple case where the number of devices is a multiple of the
+ * number of copies, we must also handle cases where the number
+ * of devices is not a multiple of the number of copies.
+ * E.g. dev1 dev2 dev3 dev4 dev5
+ * A A B B C
+ * C D D E E
+ */
+ rebuilds_per_group = 0;
+ for (i = 0; i < rs->md.raid_disks * copies; i++) {
+ d = i % rs->md.raid_disks;
+ if (!test_bit(In_sync, &rs->dev[d].rdev.flags) &&
+ (++rebuilds_per_group >= copies))
+ goto too_many;
+ if (!((i + 1) % copies))
+ rebuilds_per_group = 0;
+ }
+ break;
default:
DMERR("The rebuild parameter is not supported for %s",
rs->raid_type->name);
/* Parameters that take a numeric value are checked here */
if (!strcasecmp(key, "rebuild")) {
- if (value > rs->md.raid_disks) {
+ if (value >= rs->md.raid_disks) {
rs->ti->error = "Invalid rebuild index given";
return -EINVAL;
}
freshest = NULL;
rdev_for_each_safe(rdev, tmp, mddev) {
+ /*
+ * Skipping super_load due to DMPF_SYNC will cause
+ * the array to undergo initialization again as
+ * though it were new. This is the intended effect
+ * of the "sync" directive.
+ *
+ * When reshaping capability is added, we must ensure
+ * that the "sync" directive is disallowed during the
+ * reshape.
+ */
+ if (rs->print_flags & DMPF_SYNC)
+ continue;
+
if (!rdev->meta_bdev)
continue;
static struct target_type raid_target = {
.name = "raid",
- .version = {1, 3, 0},
+ .version = {1, 3, 1},
.module = THIS_MODULE,
.ctr = raid_ctr,
.dtr = raid_dtr,