Grow - be careful about 'delayed' reshapes.
If multiple reshapes are activated on the same devices (different partitions) then one might be forced to wait for the other to complete. As reshaping suspends access to small sections of the array at time, this cause a region to be suspended for a long time, which isn't good. To try to detect this and don't start suspending until the reshape is actually happening. This is only effective on 3.7 and later as prior kernels don't report when the delayed reshape can progress. For the earlier kernels, just give a warning. Signed-off-by; NeilBrown <neilb@suse.de>
This commit is contained in:
parent
b716f38973
commit
1f9b0e2845
34
Grow.c
34
Grow.c
|
@ -2087,6 +2087,7 @@ static int reshape_array(char *container, int fd, char *devname,
|
|||
char *msg;
|
||||
int orig_level = UnSet;
|
||||
int disks, odisks;
|
||||
int delayed;
|
||||
|
||||
struct mdu_array_info_s array;
|
||||
char *c;
|
||||
|
@ -2573,6 +2574,39 @@ started:
|
|||
break;
|
||||
}
|
||||
|
||||
/* If another array on the same devices is busy, the
|
||||
* reshape will wait for them. This would mean that
|
||||
* the first section that we suspend will stay suspended
|
||||
* for a long time. So check on that possibility
|
||||
* by looking for "DELAYED" in /proc/mdstat, and if found,
|
||||
* wait a while
|
||||
*/
|
||||
do {
|
||||
struct mdstat_ent *mds, *m;
|
||||
delayed = 0;
|
||||
mds = mdstat_read(0, 0);
|
||||
for (m = mds; m; m = mds->next)
|
||||
if (m->devnum == devname2devnum(sra->sys_name)) {
|
||||
if (m->resync &&
|
||||
m->percent == RESYNC_DELAYED)
|
||||
delayed = 1;
|
||||
if (m->resync == 0)
|
||||
/* Haven't started the reshape thread
|
||||
* yet, wait a bit
|
||||
*/
|
||||
delayed = 2;
|
||||
break;
|
||||
}
|
||||
free_mdstat(mds);
|
||||
if (delayed == 1 && get_linux_version() < 3007000) {
|
||||
pr_err("Reshape is delayed, but cannot wait carefully with this kernel.\n"
|
||||
" You might experience problems until other reshapes complete.\n");
|
||||
delayed = 0;
|
||||
}
|
||||
if (delayed)
|
||||
sleep(30 - (delayed-1) * 25);
|
||||
} while (delayed);
|
||||
|
||||
close(fd);
|
||||
if (check_env("MDADM_GROW_VERIFY"))
|
||||
fd = open(devname, O_RDONLY | O_DIRECT);
|
||||
|
|
Loading…
Reference in New Issue