aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-21 23:55:28 -0400
committerNeilBrown <neilb@suse.de>2012-05-21 23:55:28 -0400
commitbb63a7019df91933de6854a87ddc5488b49edb85 (patch)
treed67b5399be52e0cd93a2292f0fd674109d6b6a2f /drivers/md/raid10.c
parenta4a6125a074e1b08ee8ae34f700c5bca19eb9d18 (diff)
md/raid10: resize bitmap when required during reshape.
If a reshape changes the size of the array, then we can now update the bitmap to suit - so do so. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 8fe3aa469987..ae2a5a4c6bc5 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3786,8 +3786,6 @@ static int raid10_check_reshape(struct mddev *mddev)
3786 /* not factor of array size */ 3786 /* not factor of array size */
3787 return -EINVAL; 3787 return -EINVAL;
3788 3788
3789 if (mddev->bitmap)
3790 return -EBUSY;
3791 if (!enough(conf, -1)) 3789 if (!enough(conf, -1))
3792 return -EINVAL; 3790 return -EINVAL;
3793 3791
@@ -3882,6 +3880,7 @@ static int raid10_start_reshape(struct mddev *mddev)
3882 struct r10conf *conf = mddev->private; 3880 struct r10conf *conf = mddev->private;
3883 struct md_rdev *rdev; 3881 struct md_rdev *rdev;
3884 int spares = 0; 3882 int spares = 0;
3883 int ret;
3885 3884
3886 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) 3885 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
3887 return -EBUSY; 3886 return -EBUSY;
@@ -3943,6 +3942,14 @@ static int raid10_start_reshape(struct mddev *mddev)
3943 conf->reshape_progress = 0; 3942 conf->reshape_progress = 0;
3944 spin_unlock_irq(&conf->device_lock); 3943 spin_unlock_irq(&conf->device_lock);
3945 3944
3945 if (mddev->delta_disks && mddev->bitmap) {
3946 ret = bitmap_resize(mddev->bitmap,
3947 raid10_size(mddev, 0,
3948 conf->geo.raid_disks),
3949 0, 0);
3950 if (ret)
3951 goto abort;
3952 }
3946 if (mddev->delta_disks > 0) { 3953 if (mddev->delta_disks > 0) {
3947 rdev_for_each(rdev, mddev) 3954 rdev_for_each(rdev, mddev)
3948 if (rdev->raid_disk < 0 && 3955 if (rdev->raid_disk < 0 &&
@@ -3982,22 +3989,26 @@ static int raid10_start_reshape(struct mddev *mddev)
3982 mddev->sync_thread = md_register_thread(md_do_sync, mddev, 3989 mddev->sync_thread = md_register_thread(md_do_sync, mddev,
3983 "reshape"); 3990 "reshape");
3984 if (!mddev->sync_thread) { 3991 if (!mddev->sync_thread) {
3985 mddev->recovery = 0; 3992 ret = -EAGAIN;
3986 spin_lock_irq(&conf->device_lock); 3993 goto abort;
3987 conf->geo = conf->prev;
3988 mddev->raid_disks = conf->geo.raid_disks;
3989 rdev_for_each(rdev, mddev)
3990 rdev->new_data_offset = rdev->data_offset;
3991 smp_wmb();
3992 conf->reshape_progress = MaxSector;
3993 mddev->reshape_position = MaxSector;
3994 spin_unlock_irq(&conf->device_lock);
3995 return -EAGAIN;
3996 } 3994 }
3997 conf->reshape_checkpoint = jiffies; 3995 conf->reshape_checkpoint = jiffies;
3998 md_wakeup_thread(mddev->sync_thread); 3996 md_wakeup_thread(mddev->sync_thread);
3999 md_new_event(mddev); 3997 md_new_event(mddev);
4000 return 0; 3998 return 0;
3999
4000abort:
4001 mddev->recovery = 0;
4002 spin_lock_irq(&conf->device_lock);
4003 conf->geo = conf->prev;
4004 mddev->raid_disks = conf->geo.raid_disks;
4005 rdev_for_each(rdev, mddev)
4006 rdev->new_data_offset = rdev->data_offset;
4007 smp_wmb();
4008 conf->reshape_progress = MaxSector;
4009 mddev->reshape_position = MaxSector;
4010 spin_unlock_irq(&conf->device_lock);
4011 return ret;
4001} 4012}
4002 4013
4003/* Calculate the last device-address that could contain 4014/* Calculate the last device-address that could contain