aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-20 19:27:00 -0400
committerNeilBrown <neilb@suse.de>2012-05-20 19:27:00 -0400
commit2c810cddc44d6f95cef75df3f07fc0850ff92417 (patch)
tree185b35ce06656a53327dd66343f0926aa5a910d7 /drivers/md/raid5.c
parentb5e1b8cee7ad58a15d2fa79bcd7946acb592602d (diff)
md: allow a reshape operation to be reversed.
Currently a reshape operation always progresses from the start of the array to the end unless the number of devices is being reduced, in which case it progressed in the opposite direction. To reverse a partial reshape which changes the number of devices you can stop the array and re-assemble with the raid-disks numbers reversed and it will undo. However for a reshape that does not change the number of devices it is not possible to reverse the reshape in the middle - you have to wait until it completes. So add a 'reshape_direction' attribute with is either 'forwards' or 'backwards' and can be explicitly set when delta_disks is zero. This will become more important when we allow the data_offset to change in a reshape. Then the explicit statement of what direction is being used will be more useful. This can be enabled in raid5 trivially as it already supports reverse reshape and just needs to use a different trigger to request it. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index f351422938e0..0abbd3447cfb 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3970,13 +3970,13 @@ static void make_request(struct mddev *mddev, struct bio * bi)
3970 * to check again. 3970 * to check again.
3971 */ 3971 */
3972 spin_lock_irq(&conf->device_lock); 3972 spin_lock_irq(&conf->device_lock);
3973 if (mddev->delta_disks < 0 3973 if (mddev->reshape_backwards
3974 ? logical_sector < conf->reshape_progress 3974 ? logical_sector < conf->reshape_progress
3975 : logical_sector >= conf->reshape_progress) { 3975 : logical_sector >= conf->reshape_progress) {
3976 disks = conf->previous_raid_disks; 3976 disks = conf->previous_raid_disks;
3977 previous = 1; 3977 previous = 1;
3978 } else { 3978 } else {
3979 if (mddev->delta_disks < 0 3979 if (mddev->reshape_backwards
3980 ? logical_sector < conf->reshape_safe 3980 ? logical_sector < conf->reshape_safe
3981 : logical_sector >= conf->reshape_safe) { 3981 : logical_sector >= conf->reshape_safe) {
3982 spin_unlock_irq(&conf->device_lock); 3982 spin_unlock_irq(&conf->device_lock);
@@ -4009,7 +4009,7 @@ static void make_request(struct mddev *mddev, struct bio * bi)
4009 */ 4009 */
4010 int must_retry = 0; 4010 int must_retry = 0;
4011 spin_lock_irq(&conf->device_lock); 4011 spin_lock_irq(&conf->device_lock);
4012 if (mddev->delta_disks < 0 4012 if (mddev->reshape_backwards
4013 ? logical_sector >= conf->reshape_progress 4013 ? logical_sector >= conf->reshape_progress
4014 : logical_sector < conf->reshape_progress) 4014 : logical_sector < conf->reshape_progress)
4015 /* mismatch, need to try again */ 4015 /* mismatch, need to try again */
@@ -4108,11 +4108,11 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
4108 4108
4109 if (sector_nr == 0) { 4109 if (sector_nr == 0) {
4110 /* If restarting in the middle, skip the initial sectors */ 4110 /* If restarting in the middle, skip the initial sectors */
4111 if (mddev->delta_disks < 0 && 4111 if (mddev->reshape_backwards &&
4112 conf->reshape_progress < raid5_size(mddev, 0, 0)) { 4112 conf->reshape_progress < raid5_size(mddev, 0, 0)) {
4113 sector_nr = raid5_size(mddev, 0, 0) 4113 sector_nr = raid5_size(mddev, 0, 0)
4114 - conf->reshape_progress; 4114 - conf->reshape_progress;
4115 } else if (mddev->delta_disks >= 0 && 4115 } else if (!mddev->reshape_backwards &&
4116 conf->reshape_progress > 0) 4116 conf->reshape_progress > 0)
4117 sector_nr = conf->reshape_progress; 4117 sector_nr = conf->reshape_progress;
4118 sector_div(sector_nr, new_data_disks); 4118 sector_div(sector_nr, new_data_disks);
@@ -4147,7 +4147,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
4147 sector_div(readpos, data_disks); 4147 sector_div(readpos, data_disks);
4148 safepos = conf->reshape_safe; 4148 safepos = conf->reshape_safe;
4149 sector_div(safepos, data_disks); 4149 sector_div(safepos, data_disks);
4150 if (mddev->delta_disks < 0) { 4150 if (mddev->reshape_backwards) {
4151 writepos -= min_t(sector_t, reshape_sectors, writepos); 4151 writepos -= min_t(sector_t, reshape_sectors, writepos);
4152 readpos += reshape_sectors; 4152 readpos += reshape_sectors;
4153 safepos += reshape_sectors; 4153 safepos += reshape_sectors;
@@ -4174,7 +4174,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
4174 * Maybe that number should be configurable, but I'm not sure it is 4174 * Maybe that number should be configurable, but I'm not sure it is
4175 * worth it.... maybe it could be a multiple of safemode_delay??? 4175 * worth it.... maybe it could be a multiple of safemode_delay???
4176 */ 4176 */
4177 if ((mddev->delta_disks < 0 4177 if ((mddev->reshape_backwards
4178 ? (safepos > writepos && readpos < writepos) 4178 ? (safepos > writepos && readpos < writepos)
4179 : (safepos < writepos && readpos > writepos)) || 4179 : (safepos < writepos && readpos > writepos)) ||
4180 time_after(jiffies, conf->reshape_checkpoint + 10*HZ)) { 4180 time_after(jiffies, conf->reshape_checkpoint + 10*HZ)) {
@@ -4195,7 +4195,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
4195 sysfs_notify(&mddev->kobj, NULL, "sync_completed"); 4195 sysfs_notify(&mddev->kobj, NULL, "sync_completed");
4196 } 4196 }
4197 4197
4198 if (mddev->delta_disks < 0) { 4198 if (mddev->reshape_backwards) {
4199 BUG_ON(conf->reshape_progress == 0); 4199 BUG_ON(conf->reshape_progress == 0);
4200 stripe_addr = writepos; 4200 stripe_addr = writepos;
4201 BUG_ON((mddev->dev_sectors & 4201 BUG_ON((mddev->dev_sectors &
@@ -4239,7 +4239,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
4239 list_add(&sh->lru, &stripes); 4239 list_add(&sh->lru, &stripes);
4240 } 4240 }
4241 spin_lock_irq(&conf->device_lock); 4241 spin_lock_irq(&conf->device_lock);
4242 if (mddev->delta_disks < 0) 4242 if (mddev->reshape_backwards)
4243 conf->reshape_progress -= reshape_sectors * new_data_disks; 4243 conf->reshape_progress -= reshape_sectors * new_data_disks;
4244 else 4244 else
4245 conf->reshape_progress += reshape_sectors * new_data_disks; 4245 conf->reshape_progress += reshape_sectors * new_data_disks;
@@ -5008,7 +5008,7 @@ static int run(struct mddev *mddev)
5008 mdname(mddev)); 5008 mdname(mddev));
5009 return -EINVAL; 5009 return -EINVAL;
5010 } 5010 }
5011 } else if (mddev->delta_disks < 0 5011 } else if (mddev->reshape_backwards
5012 ? (here_new * mddev->new_chunk_sectors <= 5012 ? (here_new * mddev->new_chunk_sectors <=
5013 here_old * mddev->chunk_sectors) 5013 here_old * mddev->chunk_sectors)
5014 : (here_new * mddev->new_chunk_sectors >= 5014 : (here_new * mddev->new_chunk_sectors >=
@@ -5535,7 +5535,7 @@ static int raid5_start_reshape(struct mddev *mddev)
5535 conf->chunk_sectors = mddev->new_chunk_sectors; 5535 conf->chunk_sectors = mddev->new_chunk_sectors;
5536 conf->prev_algo = conf->algorithm; 5536 conf->prev_algo = conf->algorithm;
5537 conf->algorithm = mddev->new_layout; 5537 conf->algorithm = mddev->new_layout;
5538 if (mddev->delta_disks < 0) 5538 if (mddev->reshape_backwards)
5539 conf->reshape_progress = raid5_size(mddev, 0, 0); 5539 conf->reshape_progress = raid5_size(mddev, 0, 0);
5540 else 5540 else
5541 conf->reshape_progress = 0; 5541 conf->reshape_progress = 0;
@@ -5663,6 +5663,7 @@ static void raid5_finish_reshape(struct mddev *mddev)
5663 mddev->chunk_sectors = conf->chunk_sectors; 5663 mddev->chunk_sectors = conf->chunk_sectors;
5664 mddev->reshape_position = MaxSector; 5664 mddev->reshape_position = MaxSector;
5665 mddev->delta_disks = 0; 5665 mddev->delta_disks = 0;
5666 mddev->reshape_backwards = 0;
5666 } 5667 }
5667} 5668}
5668 5669