aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-06-17 18:47:20 -0400
committerNeilBrown <neilb@suse.de>2009-06-17 18:47:20 -0400
commit01ee22b496c41384eaa6dcae983c86d8bc32fbb8 (patch)
treeaeb031b03e2a8b784fcf71ed462c0aa37b7006ef /drivers/md
parentd6e412eaa52db82010f12ea7d2c9b9468e933c44 (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')
-rw-r--r--drivers/md/raid5.c44
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
4848static 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
4848static int raid5_check_reshape(mddev_t *mddev) 4871static 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))