diff options
author | NeilBrown <neilb@suse.com> | 2015-07-17 12:06:02 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.com> | 2015-08-31 19:37:33 +0200 |
commit | c5e19d906a658f27fa858b09a95d9551b1a69bd0 (patch) | |
tree | 4f24e56a076c2d544fbda272a85ba25e8d1e0242 /drivers/md/md.c | |
parent | a4a3d26d8757a30ae21724d8b0d79e00e113c38d (diff) |
md: be careful when testing resync_max against curr_resync_completed.
While it generally shouldn't happen, it is not impossible for
curr_resync_completed to exceed resync_max.
This can particularly happen when reshaping RAID5 - the current
status isn't copied to curr_resync_completed promptly, so when it
is, it can exceed resync_max.
This happens when the reshape is 'frozen', resync_max is set low,
and reshape is re-enabled.
Taking a difference between two unsigned numbers is always dangerous
anyway, so add a test to behave correctly if
curr_resync_completed > resync_max
Signed-off-by: NeilBrown <neilb@suse.com>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 5b62a3d49e12..b326cd26b027 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7834,7 +7834,8 @@ void md_do_sync(struct md_thread *thread) > (max_sectors >> 4)) || time_after_eq(jiffies, update_time + UPDATE_FREQUENCY) || (j - mddev->curr_resync_completed)*2 - >= mddev->resync_max - mddev->curr_resync_completed + >= mddev->resync_max - mddev->curr_resync_completed || + mddev->curr_resync_completed > mddev->resync_max )) { /* time to update curr_resync_completed */ wait_event(mddev->recovery_wait, |