Commit 92140480 authored by NeilBrown's avatar NeilBrown

md/raid5: consider updating reshape_position at start of reshape.

md/raid5 only updates ->reshape_position (which is stored in
metadata and is authoritative) occasionally, but particularly
when getting closed to ->resync_max as it must be correct
when ->resync_max is reached.

When mdadm tries to stop an array which is reshaping it will:
 - freeze the reshape,
 - set resync_max to where the reshape has reached.
 - unfreeze the reshape.
When this happens, the reshape is aborted and then restarted.

The restart doesn't check that resync_max is close, and so doesn't
update ->reshape_position like it should.
This results in the reshape stopping, but ->reshape_position being
incorrect.

So on that first call to reshape_request, make sure ->reshape_position
is updated if needed.
Signed-off-by: default avatarNeilBrown <neilb@suse.com>
parent 985ca973
...@@ -5347,6 +5347,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk ...@@ -5347,6 +5347,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
sector_t stripe_addr; sector_t stripe_addr;
int reshape_sectors; int reshape_sectors;
struct list_head stripes; struct list_head stripes;
sector_t retn;
if (sector_nr == 0) { if (sector_nr == 0) {
/* If restarting in the middle, skip the initial sectors */ /* If restarting in the middle, skip the initial sectors */
...@@ -5362,7 +5363,8 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk ...@@ -5362,7 +5363,8 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
mddev->curr_resync_completed = sector_nr; mddev->curr_resync_completed = sector_nr;
sysfs_notify(&mddev->kobj, NULL, "sync_completed"); sysfs_notify(&mddev->kobj, NULL, "sync_completed");
*skipped = 1; *skipped = 1;
return sector_nr; retn = sector_nr;
goto finish;
} }
} }
...@@ -5535,6 +5537,8 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk ...@@ -5535,6 +5537,8 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
* then we need to write out the superblock. * then we need to write out the superblock.
*/ */
sector_nr += reshape_sectors; sector_nr += reshape_sectors;
retn = reshape_sectors;
finish:
if ((sector_nr - mddev->curr_resync_completed) * 2 if ((sector_nr - mddev->curr_resync_completed) * 2
>= mddev->resync_max - mddev->curr_resync_completed) { >= mddev->resync_max - mddev->curr_resync_completed) {
/* Cannot proceed until we've updated the superblock... */ /* Cannot proceed until we've updated the superblock... */
...@@ -5560,7 +5564,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk ...@@ -5560,7 +5564,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
sysfs_notify(&mddev->kobj, NULL, "sync_completed"); sysfs_notify(&mddev->kobj, NULL, "sync_completed");
} }
ret: ret:
return reshape_sectors; return retn;
} }
static inline sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipped) static inline sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipped)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment