diff options
author | NeilBrown <neilb@suse.de> | 2011-07-27 17:26:12 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-07-27 17:26:12 +1000 |
commit | 6560987b25a88f78ed53d37525d363c126a07b79 (patch) | |
tree | c75a1faafac1760242e49852211f9596f0fc4d5c | |
parent | 656b6b5a55adb1fd223d82478c333264af52877a (diff) | |
download | mdadm-6560987b25a88f78ed53d37525d363c126a07b79.tar.gz |
Grow: ensure clean abort if we cannot read the 'completed' file.
If a read of 'completed' returns an error, select will never fail, so
this loop would never exit.
Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r-- | Grow.c | 10 | ||||
-rw-r--r-- | sysfs.c | 2 |
2 files changed, 9 insertions, 3 deletions
@@ -2725,15 +2725,21 @@ check_progress: int rv = -2; tv.tv_sec = 10; tv.tv_usec = 0; - while (fd >= 0 && rv < 0) { + while (fd >= 0 && rv < 0 && tv.tv_sec > 0) { fd_set rfds; FD_ZERO(&rfds); FD_SET(fd, &rfds); if (select(fd+1, NULL, NULL, &rfds, &tv) != 1) break; - if (sysfs_fd_get_ll(fd, &completed) >= 0) + switch (sysfs_fd_get_ll(fd, &completed)) { + case 0: /* all good again */ rv = 1; + break; + case -2: /* read error - abort */ + tv.tv_sec = 0; + break; + } } if (fd >= 0) close(fd); @@ -470,7 +470,7 @@ int sysfs_fd_get_ll(int fd, unsigned long long *val) lseek(fd, 0, 0); n = read(fd, buf, sizeof(buf)); if (n <= 0) - return -1; + return -2; buf[n] = 0; *val = strtoull(buf, &ep, 0); if (ep == buf || (*ep != 0 && *ep != '\n' && *ep != ' ')) |