提交 01ee22b4 编写于 作者: N NeilBrown

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: NNeilBrown <neilb@suse.de>
上级 d6e412ea
...@@ -4845,6 +4845,29 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors) ...@@ -4845,6 +4845,29 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
return 0; return 0;
} }
static int check_stripe_cache(mddev_t *mddev)
{
/* Can only proceed if there are plenty of stripe_heads.
* We need a minimum of one full stripe,, and for sensible progress
* it is best to have about 4 times that.
* If we require 4 times, then the default 256 4K stripe_heads will
* allow for chunk sizes up to 256K, which is probably OK.
* If the chunk size is greater, user-space should request more
* stripe_heads first.
*/
raid5_conf_t *conf = mddev->private;
if (((mddev->chunk_sectors << 9) / STRIPE_SIZE) * 4
> conf->max_nr_stripes ||
((mddev->new_chunk_sectors << 9) / STRIPE_SIZE) * 4
> conf->max_nr_stripes) {
printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n",
((max(mddev->chunk_sectors, mddev->new_chunk_sectors) << 9)
/ STRIPE_SIZE)*4);
return 0;
}
return 1;
}
static int raid5_check_reshape(mddev_t *mddev) static int raid5_check_reshape(mddev_t *mddev)
{ {
raid5_conf_t *conf = mddev->private; raid5_conf_t *conf = mddev->private;
...@@ -4871,24 +4894,8 @@ static int raid5_check_reshape(mddev_t *mddev) ...@@ -4871,24 +4894,8 @@ static int raid5_check_reshape(mddev_t *mddev)
return -EINVAL; return -EINVAL;
} }
/* Can only proceed if there are plenty of stripe_heads. if (!check_stripe_cache(mddev))
* We need a minimum of one full stripe,, and for sensible progress
* it is best to have about 4 times that.
* If we require 4 times, then the default 256 4K stripe_heads will
* allow for chunk sizes up to 256K, which is probably OK.
* If the chunk size is greater, user-space should request more
* stripe_heads first.
*/
if (((mddev->chunk_sectors << 9) / STRIPE_SIZE) * 4
> conf->max_nr_stripes ||
((mddev->new_chunk_sectors << 9) / STRIPE_SIZE) * 4
> conf->max_nr_stripes) {
printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n",
(max(mddev->chunk_sectors << 9,
mddev->new_chunk_sectors << 9)
/ STRIPE_SIZE)*4);
return -ENOSPC; return -ENOSPC;
}
return resize_stripes(conf, conf->raid_disks + mddev->delta_disks); return resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
} }
...@@ -4904,6 +4911,9 @@ static int raid5_start_reshape(mddev_t *mddev) ...@@ -4904,6 +4911,9 @@ static int raid5_start_reshape(mddev_t *mddev)
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
return -EBUSY; return -EBUSY;
if (!check_stripe_cache(mddev))
return -ENOSPC;
list_for_each_entry(rdev, &mddev->disks, same_set) list_for_each_entry(rdev, &mddev->disks, same_set)
if (rdev->raid_disk < 0 && if (rdev->raid_disk < 0 &&
!test_bit(Faulty, &rdev->flags)) !test_bit(Faulty, &rdev->flags))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册