From bb63a7019df91933de6854a87ddc5488b49edb85 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 22 May 2012 13:55:28 +1000 Subject: 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 --- drivers/md/raid10.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'drivers/md') 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) /* not factor of array size */ return -EINVAL; - if (mddev->bitmap) - return -EBUSY; if (!enough(conf, -1)) return -EINVAL; @@ -3882,6 +3880,7 @@ static int raid10_start_reshape(struct mddev *mddev) struct r10conf *conf = mddev->private; struct md_rdev *rdev; int spares = 0; + int ret; if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) return -EBUSY; @@ -3943,6 +3942,14 @@ static int raid10_start_reshape(struct mddev *mddev) conf->reshape_progress = 0; spin_unlock_irq(&conf->device_lock); + if (mddev->delta_disks && mddev->bitmap) { + ret = bitmap_resize(mddev->bitmap, + raid10_size(mddev, 0, + conf->geo.raid_disks), + 0, 0); + if (ret) + goto abort; + } if (mddev->delta_disks > 0) { rdev_for_each(rdev, mddev) if (rdev->raid_disk < 0 && @@ -3982,22 +3989,26 @@ static int raid10_start_reshape(struct mddev *mddev) mddev->sync_thread = md_register_thread(md_do_sync, mddev, "reshape"); if (!mddev->sync_thread) { - mddev->recovery = 0; - spin_lock_irq(&conf->device_lock); - conf->geo = conf->prev; - mddev->raid_disks = conf->geo.raid_disks; - rdev_for_each(rdev, mddev) - rdev->new_data_offset = rdev->data_offset; - smp_wmb(); - conf->reshape_progress = MaxSector; - mddev->reshape_position = MaxSector; - spin_unlock_irq(&conf->device_lock); - return -EAGAIN; + ret = -EAGAIN; + goto abort; } conf->reshape_checkpoint = jiffies; md_wakeup_thread(mddev->sync_thread); md_new_event(mddev); return 0; + +abort: + mddev->recovery = 0; + spin_lock_irq(&conf->device_lock); + conf->geo = conf->prev; + mddev->raid_disks = conf->geo.raid_disks; + rdev_for_each(rdev, mddev) + rdev->new_data_offset = rdev->data_offset; + smp_wmb(); + conf->reshape_progress = MaxSector; + mddev->reshape_position = MaxSector; + spin_unlock_irq(&conf->device_lock); + return ret; } /* Calculate the last device-address that could contain -- cgit v1.2.3