diff options
author | NeilBrown <neilb@suse.de> | 2013-07-04 17:16:20 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2013-07-04 17:18:24 +1000 |
commit | a6b2d86c624dd43ede83570ac0b254bcb98ca1d9 (patch) | |
tree | 13de642fbab65e07fdc3b11ff1417b224058abea /Grow.c | |
parent | 737f8574cdba8ac97e709c75a99088e83f5552b1 (diff) |
Grow: notice when --stop is synchronising a reshape and don't mess it up.
--stop now tries to wait for a reshape to be at just the right spot.
However for a reducing reshape, mdadm will be running in the
background watching, and might adjust sync_max and mess things up.
So teach "progress_reshape" to notice when "sync_max" is modified, and
leave it alone.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Grow.c')
-rw-r--r-- | Grow.c | 15 |
1 files changed, 12 insertions, 3 deletions
@@ -3526,7 +3526,7 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape, unsigned long long backup_point, unsigned long long wait_point, unsigned long long *suspend_point, - unsigned long long *reshape_completed) + unsigned long long *reshape_completed, int *frozen) { /* This function is called repeatedly by the reshape manager. * It determines how much progress can safely be made and allows @@ -3743,7 +3743,8 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape, wait_point = info->component_size - wait_point; } - sysfs_set_num(info, NULL, "sync_max", max_progress); + if (!*frozen) + sysfs_set_num(info, NULL, "sync_max", max_progress); /* Now wait. If we have already reached the point that we were * asked to wait to, don't wait at all, else wait for any change. @@ -3825,6 +3826,7 @@ check_progress: */ int wait = 10000; int rv = -2; + unsigned long long new_sync_max; while (fd >= 0 && rv < 0 && wait > 0) { if (sysfs_wait(fd, &wait) != 1) break; @@ -3832,6 +3834,11 @@ check_progress: case 0: /* all good again */ rv = 1; + /* If "sync_max" is no longer max_progress + * we need to freeze things + */ + sysfs_get_ll(info, NULL, "sync_max", &new_sync_max); + *frozen = (new_sync_max != max_progress); break; case -2: /* read error - abort */ wait = 0; @@ -4126,6 +4133,7 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape, struct mdinfo *sd; unsigned long stripes; int uuid[4]; + int frozen = 0; /* set up the backup-super-block. This requires the * uuid from the array. @@ -4206,7 +4214,8 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape, reshape_completed = sra->reshape_progress; rv = progress_reshape(sra, reshape, backup_point, wait_point, - &suspend_point, &reshape_completed); + &suspend_point, &reshape_completed, + &frozen); /* external metadata would need to ping_monitor here */ sra->reshape_progress = reshape_completed; |