Grow: fix hang when reshape completes too fast

For short reshapes the kernel may be done before mdadm can check that
progress has passed the critical section.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
Dan Williams 2009-04-12 00:58:28 -07:00
parent 506ffd1e0b
commit 48924014b0
3 changed files with 30 additions and 0 deletions

8
Grow.c
View File

@ -809,12 +809,20 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
/* wait for reshape to pass the critical region */
while(1) {
unsigned long long comp;
char a[20];
if (sysfs_get_ll(sra, NULL, "sync_completed", &comp)<0) {
sleep(5);
break;
}
if (comp >= nstripe)
break;
/* perhaps the entire reshape has completed */
if (comp == 0 &&
sysfs_get_str(sra, NULL, "sync_action", a, sizeof(a)) == 0 &&
strncmp(a, "idle", 4) == 0)
break;
sleep(1);
}

View File

@ -372,6 +372,8 @@ extern int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
extern int sysfs_uevent(struct mdinfo *sra, char *event);
extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long *val);
extern int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *buf, int buf_len);
extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);
extern int sysfs_set_array(struct mdinfo *info, int vers);
extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd);

20
sysfs.c
View File

@ -466,6 +466,26 @@ int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
return 0;
}
int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *buf, int buf_len)
{
char fname[50];
int n;
int fd;
sprintf(fname, "/sys/block/%s/md/%s/%s",
sra->sys_name, dev?dev->sys_name:"", name);
fd = open(fname, O_RDONLY);
if (fd < 0)
return -1;
n = read(fd, buf, buf_len);
close(fd);
if (n <= 0)
return -1;
buf[n] = 0;
return 0;
}
int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms)
{
unsigned long sec;