aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 80ec9a6d8a18..f7fb2b87ad89 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3738,6 +3738,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3738 int dd_idx; 3738 int dd_idx;
3739 sector_t writepos, safepos, gap; 3739 sector_t writepos, safepos, gap;
3740 sector_t stripe_addr; 3740 sector_t stripe_addr;
3741 int reshape_sectors;
3741 3742
3742 if (sector_nr == 0) { 3743 if (sector_nr == 0) {
3743 /* If restarting in the middle, skip the initial sectors */ 3744 /* If restarting in the middle, skip the initial sectors */
@@ -3755,6 +3756,15 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3755 } 3756 }
3756 } 3757 }
3757 3758
3759 /* We need to process a full chunk at a time.
3760 * If old and new chunk sizes differ, we need to process the
3761 * largest of these
3762 */
3763 if (mddev->new_chunk > mddev->chunk_size)
3764 reshape_sectors = mddev->new_chunk / 512;
3765 else
3766 reshape_sectors = mddev->chunk_size / 512;
3767
3758 /* we update the metadata when there is more than 3Meg 3768 /* we update the metadata when there is more than 3Meg
3759 * in the block range (that is rather arbitrary, should 3769 * in the block range (that is rather arbitrary, should
3760 * probably be time based) or when the data about to be 3770 * probably be time based) or when the data about to be
@@ -3768,12 +3778,12 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3768 safepos = conf->reshape_safe; 3778 safepos = conf->reshape_safe;
3769 sector_div(safepos, data_disks); 3779 sector_div(safepos, data_disks);
3770 if (mddev->delta_disks < 0) { 3780 if (mddev->delta_disks < 0) {
3771 writepos -= conf->chunk_size/512; 3781 writepos -= reshape_sectors;
3772 safepos += conf->chunk_size/512; 3782 safepos += reshape_sectors;
3773 gap = conf->reshape_safe - conf->reshape_progress; 3783 gap = conf->reshape_safe - conf->reshape_progress;
3774 } else { 3784 } else {
3775 writepos += conf->chunk_size/512; 3785 writepos += reshape_sectors;
3776 safepos -= conf->chunk_size/512; 3786 safepos -= reshape_sectors;
3777 gap = conf->reshape_progress - conf->reshape_safe; 3787 gap = conf->reshape_progress - conf->reshape_safe;
3778 } 3788 }
3779 3789
@@ -3799,14 +3809,14 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3799 BUG_ON(conf->reshape_progress == 0); 3809 BUG_ON(conf->reshape_progress == 0);
3800 stripe_addr = writepos; 3810 stripe_addr = writepos;
3801 BUG_ON((mddev->dev_sectors & 3811 BUG_ON((mddev->dev_sectors &
3802 ~((sector_t)conf->chunk_size / 512 - 1)) 3812 ~((sector_t)reshape_sectors - 1))
3803 - (conf->chunk_size / 512) - stripe_addr 3813 - reshape_sectors - stripe_addr
3804 != sector_nr); 3814 != sector_nr);
3805 } else { 3815 } else {
3806 BUG_ON(writepos != sector_nr + conf->chunk_size / 512); 3816 BUG_ON(writepos != sector_nr + reshape_sectors);
3807 stripe_addr = sector_nr; 3817 stripe_addr = sector_nr;
3808 } 3818 }
3809 for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) { 3819 for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) {
3810 int j; 3820 int j;
3811 int skipped = 0; 3821 int skipped = 0;
3812 sh = get_active_stripe(conf, stripe_addr+i, 0, 0); 3822 sh = get_active_stripe(conf, stripe_addr+i, 0, 0);
@@ -3839,9 +3849,9 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3839 } 3849 }
3840 spin_lock_irq(&conf->device_lock); 3850 spin_lock_irq(&conf->device_lock);
3841 if (mddev->delta_disks < 0) 3851 if (mddev->delta_disks < 0)
3842 conf->reshape_progress -= i * new_data_disks; 3852 conf->reshape_progress -= reshape_sectors * new_data_disks;
3843 else 3853 else
3844 conf->reshape_progress += i * new_data_disks; 3854 conf->reshape_progress += reshape_sectors * new_data_disks;
3845 spin_unlock_irq(&conf->device_lock); 3855 spin_unlock_irq(&conf->device_lock);
3846 /* Ok, those stripe are ready. We can start scheduling 3856 /* Ok, those stripe are ready. We can start scheduling
3847 * reads on the source stripes. 3857 * reads on the source stripes.
@@ -3867,7 +3877,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3867 /* If this takes us to the resync_max point where we have to pause, 3877 /* If this takes us to the resync_max point where we have to pause,
3868 * then we need to write out the superblock. 3878 * then we need to write out the superblock.
3869 */ 3879 */
3870 sector_nr += conf->chunk_size>>9; 3880 sector_nr += reshape_sectors;
3871 if (sector_nr >= mddev->resync_max) { 3881 if (sector_nr >= mddev->resync_max) {
3872 /* Cannot proceed until we've updated the superblock... */ 3882 /* Cannot proceed until we've updated the superblock... */
3873 wait_event(conf->wait_for_overlap, 3883 wait_event(conf->wait_for_overlap,
@@ -3883,7 +3893,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3883 spin_unlock_irq(&conf->device_lock); 3893 spin_unlock_irq(&conf->device_lock);
3884 wake_up(&conf->wait_for_overlap); 3894 wake_up(&conf->wait_for_overlap);
3885 } 3895 }
3886 return conf->chunk_size>>9; 3896 return reshape_sectors;
3887} 3897}
3888 3898
3889/* FIXME go_faster isn't used */ 3899/* FIXME go_faster isn't used */