Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] md: fix raid10 assembly when too many devices are missing

If you try to assemble an array with too many missing devices, raid10 will now
reject the attempt, instead of allowing it.

Also check when hot-adding a drive and refuse the hot-add if the array is
beyond hope.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

NeilBrown and committed by
Linus Torvalds
6d508242 61181565

+27 -3
+27 -3
drivers/md/raid10.c
··· 906 906 conf->r10buf_pool = NULL; 907 907 } 908 908 909 + /* check if there are enough drives for 910 + * every block to appear on atleast one 911 + */ 912 + static int enough(conf_t *conf) 913 + { 914 + int first = 0; 915 + 916 + do { 917 + int n = conf->copies; 918 + int cnt = 0; 919 + while (n--) { 920 + if (conf->mirrors[first].rdev) 921 + cnt++; 922 + first = (first+1) % conf->raid_disks; 923 + } 924 + if (cnt == 0) 925 + return 0; 926 + } while (first != 0); 927 + return 1; 928 + } 929 + 909 930 static int raid10_spare_active(mddev_t *mddev) 910 931 { 911 932 int i; ··· 964 943 /* only hot-add to in-sync arrays, as recovery is 965 944 * very different from resync 966 945 */ 946 + return 0; 947 + if (!enough(conf)) 967 948 return 0; 968 949 969 950 for (mirror=0; mirror < mddev->raid_disks; mirror++) ··· 1707 1684 init_waitqueue_head(&conf->wait_idle); 1708 1685 init_waitqueue_head(&conf->wait_resume); 1709 1686 1710 - if (!conf->working_disks) { 1711 - printk(KERN_ERR "raid10: no operational mirrors for %s\n", 1712 - mdname(mddev)); 1687 + /* need to check that every block has at least one working mirror */ 1688 + if (!enough(conf)) { 1689 + printk(KERN_ERR "raid10: not enough operational mirrors for %s\n", 1690 + mdname(mddev)); 1713 1691 goto out_free_conf; 1714 1692 } 1715 1693