diff options
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 34 |
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 */ |