mirror of https://gitee.com/openkylin/linux.git
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: NeilBrown <neilb@suse.com>
This commit is contained in:
parent
985ca973b6
commit
92140480ed
|
@ -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
|
||||||
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
|
||||||
* 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
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue