diff options
author | NeilBrown <neilb@suse.de> | 2009-06-17 18:47:20 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2009-06-17 18:47:20 -0400 |
commit | 01ee22b496c41384eaa6dcae983c86d8bc32fbb8 (patch) | |
tree | aeb031b03e2a8b784fcf71ed462c0aa37b7006ef /drivers/md/raid5.c | |
parent | d6e412eaa52db82010f12ea7d2c9b9468e933c44 (diff) |
md: raid5: check stripe cache is large enough in start_reshape
In reshape cases that do not change the number of devices,
start_reshape is called without first calling check_reshape.
Currently, the check that the stripe_cache is large enough is
only done in check_reshape. It should be in start_reshape too.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 009344156751..b84766e347c3 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -4845,6 +4845,29 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors) | |||
4845 | return 0; | 4845 | return 0; |
4846 | } | 4846 | } |
4847 | 4847 | ||
4848 | static int check_stripe_cache(mddev_t *mddev) | ||
4849 | { | ||
4850 | /* Can only proceed if there are plenty of stripe_heads. | ||
4851 | * We need a minimum of one full stripe,, and for sensible progress | ||
4852 | * it is best to have about 4 times that. | ||
4853 | * If we require 4 times, then the default 256 4K stripe_heads will | ||
4854 | * allow for chunk sizes up to 256K, which is probably OK. | ||
4855 | * If the chunk size is greater, user-space should request more | ||
4856 | * stripe_heads first. | ||
4857 | */ | ||
4858 | raid5_conf_t *conf = mddev->private; | ||
4859 | if (((mddev->chunk_sectors << 9) / STRIPE_SIZE) * 4 | ||
4860 | > conf->max_nr_stripes || | ||
4861 | ((mddev->new_chunk_sectors << 9) / STRIPE_SIZE) * 4 | ||
4862 | > conf->max_nr_stripes) { | ||
4863 | printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n", | ||
4864 | ((max(mddev->chunk_sectors, mddev->new_chunk_sectors) << 9) | ||
4865 | / STRIPE_SIZE)*4); | ||
4866 | return 0; | ||
4867 | } | ||
4868 | return 1; | ||
4869 | } | ||
4870 | |||
4848 | static int raid5_check_reshape(mddev_t *mddev) | 4871 | static int raid5_check_reshape(mddev_t *mddev) |
4849 | { | 4872 | { |
4850 | raid5_conf_t *conf = mddev->private; | 4873 | raid5_conf_t *conf = mddev->private; |
@@ -4871,24 +4894,8 @@ static int raid5_check_reshape(mddev_t *mddev) | |||
4871 | return -EINVAL; | 4894 | return -EINVAL; |
4872 | } | 4895 | } |
4873 | 4896 | ||
4874 | /* Can only proceed if there are plenty of stripe_heads. | 4897 | if (!check_stripe_cache(mddev)) |
4875 | * We need a minimum of one full stripe,, and for sensible progress | ||
4876 | * it is best to have about 4 times that. | ||
4877 | * If we require 4 times, then the default 256 4K stripe_heads will | ||
4878 | * allow for chunk sizes up to 256K, which is probably OK. | ||
4879 | * If the chunk size is greater, user-space should request more | ||
4880 | * stripe_heads first. | ||
4881 | */ | ||
4882 | if (((mddev->chunk_sectors << 9) / STRIPE_SIZE) * 4 | ||
4883 | > conf->max_nr_stripes || | ||
4884 | ((mddev->new_chunk_sectors << 9) / STRIPE_SIZE) * 4 | ||
4885 | > conf->max_nr_stripes) { | ||
4886 | printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n", | ||
4887 | (max(mddev->chunk_sectors << 9, | ||
4888 | mddev->new_chunk_sectors << 9) | ||
4889 | / STRIPE_SIZE)*4); | ||
4890 | return -ENOSPC; | 4898 | return -ENOSPC; |
4891 | } | ||
4892 | 4899 | ||
4893 | return resize_stripes(conf, conf->raid_disks + mddev->delta_disks); | 4900 | return resize_stripes(conf, conf->raid_disks + mddev->delta_disks); |
4894 | } | 4901 | } |
@@ -4904,6 +4911,9 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
4904 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | 4911 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
4905 | return -EBUSY; | 4912 | return -EBUSY; |
4906 | 4913 | ||
4914 | if (!check_stripe_cache(mddev)) | ||
4915 | return -ENOSPC; | ||
4916 | |||
4907 | list_for_each_entry(rdev, &mddev->disks, same_set) | 4917 | list_for_each_entry(rdev, &mddev->disks, same_set) |
4908 | if (rdev->raid_disk < 0 && | 4918 | if (rdev->raid_disk < 0 && |
4909 | !test_bit(Faulty, &rdev->flags)) | 4919 | !test_bit(Faulty, &rdev->flags)) |