summaryrefslogtreecommitdiff
path: root/Grow.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-07-04 17:16:20 +1000
committerNeilBrown <neilb@suse.de>2013-07-04 17:18:24 +1000
commita6b2d86c624dd43ede83570ac0b254bcb98ca1d9 (patch)
tree13de642fbab65e07fdc3b11ff1417b224058abea /Grow.c
parent737f8574cdba8ac97e709c75a99088e83f5552b1 (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.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/Grow.c b/Grow.c
index 20ecf3fd..7baa5f8a 100644
--- a/Grow.c
+++ b/Grow.c
@@ -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;