aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-raid.c
diff options
context:
space:
mode:
authorJonathan Brassow <jbrassow@redhat.com>2013-01-22 22:42:18 -0500
committerNeilBrown <neilb@suse.de>2013-01-23 20:02:36 -0500
commit55ebbb59c1c6eb1b040f62b8c4ae0b724de6e55a (patch)
tree93c97e2afe99e3cc329ec5dcd941f968a4729abb /drivers/md/dm-raid.c
parent5f243b9b46a22e5790dbbc36f574c2417af49a41 (diff)
DM-RAID: Fix RAID10's check for sufficient redundancy
Before attempting to activate a RAID array, it is checked for sufficient redundancy. That is, we make sure that there are not too many failed devices - or devices specified for rebuild - to undermine our ability to activate the array. The current code performs this check twice - once to ensure there were not too many devices specified for rebuild by the user ('validate_rebuild_devices') and again after possibly experiencing a failure to read the superblock ('analyse_superblocks'). Neither of these checks are sufficient. The first check is done properly but with insufficient information about the possible failure state of the devices to make a good determination if the array can be activated. The second check is simply done wrong in the case of RAID10 because it doesn't account for the independence of the stripes (i.e. mirror sets). The solution is to use the properly written check ('validate_rebuild_devices'), but perform the check after the superblocks have been read and we know which devices have failed. This gives us one check instead of two and performs it in a location where it can be done right. Only RAID10 was affected and it was affected in the following ways: - the code did not properly catch the condition where a user specified a device for rebuild that already had a failed device in the same mirror set. (This condition would, however, be caught at a deeper level in MD.) - the code triggers a false positive and denies activation when devices in independent mirror sets have failed - counting the failures as though they were all in the same set. The most likely place this error was introduced (or this patch should have been included) is in commit 4ec1e369 - first introduced in v3.7-rc1. Consequently this fix should also go in v3.7.y, however there is a small conflict on the .version in raid_target, so I'll submit a separate patch to -stable. Cc: stable@vger.kernel.org Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/dm-raid.c')
-rw-r--r--drivers/md/dm-raid.c101
1 files changed, 37 insertions, 64 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 3d8984edeff7..9e58dbd8d8cb 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -340,24 +340,22 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
340} 340}
341 341
342/* 342/*
343 * validate_rebuild_devices 343 * validate_raid_redundancy
344 * @rs 344 * @rs
345 * 345 *
346 * Determine if the devices specified for rebuild can result in a valid 346 * Determine if there are enough devices in the array that haven't
347 * usable array that is capable of rebuilding the given devices. 347 * failed (or are being rebuilt) to form a usable array.
348 * 348 *
349 * Returns: 0 on success, -EINVAL on failure. 349 * Returns: 0 on success, -EINVAL on failure.
350 */ 350 */
351static int validate_rebuild_devices(struct raid_set *rs) 351static int validate_raid_redundancy(struct raid_set *rs)
352{ 352{
353 unsigned i, rebuild_cnt = 0; 353 unsigned i, rebuild_cnt = 0;
354 unsigned rebuilds_per_group, copies, d; 354 unsigned rebuilds_per_group, copies, d;
355 355
356 if (!(rs->print_flags & DMPF_REBUILD))
357 return 0;
358
359 for (i = 0; i < rs->md.raid_disks; i++) 356 for (i = 0; i < rs->md.raid_disks; i++)
360 if (!test_bit(In_sync, &rs->dev[i].rdev.flags)) 357 if (!test_bit(In_sync, &rs->dev[i].rdev.flags) ||
358 !rs->dev[i].rdev.sb_page)
361 rebuild_cnt++; 359 rebuild_cnt++;
362 360
363 switch (rs->raid_type->level) { 361 switch (rs->raid_type->level) {
@@ -393,27 +391,24 @@ static int validate_rebuild_devices(struct raid_set *rs)
393 * A A B B C 391 * A A B B C
394 * C D D E E 392 * C D D E E
395 */ 393 */
396 rebuilds_per_group = 0;
397 for (i = 0; i < rs->md.raid_disks * copies; i++) { 394 for (i = 0; i < rs->md.raid_disks * copies; i++) {
395 if (!(i % copies))
396 rebuilds_per_group = 0;
398 d = i % rs->md.raid_disks; 397 d = i % rs->md.raid_disks;
399 if (!test_bit(In_sync, &rs->dev[d].rdev.flags) && 398 if ((!rs->dev[d].rdev.sb_page ||
399 !test_bit(In_sync, &rs->dev[d].rdev.flags)) &&
400 (++rebuilds_per_group >= copies)) 400 (++rebuilds_per_group >= copies))
401 goto too_many; 401 goto too_many;
402 if (!((i + 1) % copies))
403 rebuilds_per_group = 0;
404 } 402 }
405 break; 403 break;
406 default: 404 default:
407 DMERR("The rebuild parameter is not supported for %s", 405 if (rebuild_cnt)
408 rs->raid_type->name); 406 return -EINVAL;
409 rs->ti->error = "Rebuild not supported for this RAID type";
410 return -EINVAL;
411 } 407 }
412 408
413 return 0; 409 return 0;
414 410
415too_many: 411too_many:
416 rs->ti->error = "Too many rebuild devices specified";
417 return -EINVAL; 412 return -EINVAL;
418} 413}
419 414
@@ -664,9 +659,6 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
664 } 659 }
665 rs->md.dev_sectors = sectors_per_dev; 660 rs->md.dev_sectors = sectors_per_dev;
666 661
667 if (validate_rebuild_devices(rs))
668 return -EINVAL;
669
670 /* Assume there are no metadata devices until the drives are parsed */ 662 /* Assume there are no metadata devices until the drives are parsed */
671 rs->md.persistent = 0; 663 rs->md.persistent = 0;
672 rs->md.external = 1; 664 rs->md.external = 1;
@@ -995,28 +987,10 @@ static int super_validate(struct mddev *mddev, struct md_rdev *rdev)
995static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) 987static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
996{ 988{
997 int ret; 989 int ret;
998 unsigned redundancy = 0;
999 struct raid_dev *dev; 990 struct raid_dev *dev;
1000 struct md_rdev *rdev, *tmp, *freshest; 991 struct md_rdev *rdev, *tmp, *freshest;
1001 struct mddev *mddev = &rs->md; 992 struct mddev *mddev = &rs->md;
1002 993
1003 switch (rs->raid_type->level) {
1004 case 1:
1005 redundancy = rs->md.raid_disks - 1;
1006 break;
1007 case 4:
1008 case 5:
1009 case 6:
1010 redundancy = rs->raid_type->parity_devs;
1011 break;
1012 case 10:
1013 redundancy = raid10_md_layout_to_copies(mddev->layout) - 1;
1014 break;
1015 default:
1016 ti->error = "Unknown RAID type";
1017 return -EINVAL;
1018 }
1019
1020 freshest = NULL; 994 freshest = NULL;
1021 rdev_for_each_safe(rdev, tmp, mddev) { 995 rdev_for_each_safe(rdev, tmp, mddev) {
1022 /* 996 /*
@@ -1045,44 +1019,43 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
1045 break; 1019 break;
1046 default: 1020 default:
1047 dev = container_of(rdev, struct raid_dev, rdev); 1021 dev = container_of(rdev, struct raid_dev, rdev);
1048 if (redundancy--) { 1022 if (dev->meta_dev)
1049 if (dev->meta_dev) 1023 dm_put_device(ti, dev->meta_dev);
1050 dm_put_device(ti, dev->meta_dev);
1051
1052 dev->meta_dev = NULL;
1053 rdev->meta_bdev = NULL;
1054 1024
1055 if (rdev->sb_page) 1025 dev->meta_dev = NULL;
1056 put_page(rdev->sb_page); 1026 rdev->meta_bdev = NULL;
1057 1027
1058 rdev->sb_page = NULL; 1028 if (rdev->sb_page)
1029 put_page(rdev->sb_page);
1059 1030
1060 rdev->sb_loaded = 0; 1031 rdev->sb_page = NULL;
1061 1032
1062 /* 1033 rdev->sb_loaded = 0;
1063 * We might be able to salvage the data device
1064 * even though the meta device has failed. For
1065 * now, we behave as though '- -' had been
1066 * set for this device in the table.
1067 */
1068 if (dev->data_dev)
1069 dm_put_device(ti, dev->data_dev);
1070 1034
1071 dev->data_dev = NULL; 1035 /*
1072 rdev->bdev = NULL; 1036 * We might be able to salvage the data device
1037 * even though the meta device has failed. For
1038 * now, we behave as though '- -' had been
1039 * set for this device in the table.
1040 */
1041 if (dev->data_dev)
1042 dm_put_device(ti, dev->data_dev);
1073 1043
1074 list_del(&rdev->same_set); 1044 dev->data_dev = NULL;
1045 rdev->bdev = NULL;
1075 1046
1076 continue; 1047 list_del(&rdev->same_set);
1077 }
1078 ti->error = "Failed to load superblock";
1079 return ret;
1080 } 1048 }
1081 } 1049 }
1082 1050
1083 if (!freshest) 1051 if (!freshest)
1084 return 0; 1052 return 0;
1085 1053
1054 if (validate_raid_redundancy(rs)) {
1055 rs->ti->error = "Insufficient redundancy to activate array";
1056 return -EINVAL;
1057 }
1058
1086 /* 1059 /*
1087 * Validation of the freshest device provides the source of 1060 * Validation of the freshest device provides the source of
1088 * validation for the remaining devices. 1061 * validation for the remaining devices.
@@ -1432,7 +1405,7 @@ static void raid_resume(struct dm_target *ti)
1432 1405
1433static struct target_type raid_target = { 1406static struct target_type raid_target = {
1434 .name = "raid", 1407 .name = "raid",
1435 .version = {1, 4, 0}, 1408 .version = {1, 4, 1},
1436 .module = THIS_MODULE, 1409 .module = THIS_MODULE,
1437 .ctr = raid_ctr, 1410 .ctr = raid_ctr,
1438 .dtr = raid_dtr, 1411 .dtr = raid_dtr,