diff options
author | NeilBrown <neilb@suse.de> | 2013-07-01 07:10:05 +0200 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2013-07-01 07:10:05 +0200 |
commit | 2eba849621011a5160b4597f82aa4ed0de7d4e64 (patch) | |
tree | bc692036f3889927542d9d0d1b12a8b305e082f9 /sysfs.c | |
parent | New function: sysfs_wait (diff) | |
download | mdadm-2eba849621011a5160b4597f82aa4ed0de7d4e64.tar.xz mdadm-2eba849621011a5160b4597f82aa4ed0de7d4e64.zip |
Manage: check alignment when stopping an array undergoing reshape.
To be able to revert-reshape of raid4/5/6 which is changing
the number of devices, the reshape must has been stopped on a multiple
of the old and new stripe sizes.
The kernel only enforces the new stripe size multiple.
So we enforce the old-stripe-size multiple by careful use of
"sync_max" and monitoring "reshape_position".
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'sysfs.c')
-rw-r--r-- | sysfs.c | 43 |
1 files changed, 43 insertions, 0 deletions
@@ -513,6 +513,49 @@ int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev, return n; } +int sysfs_fd_get_two(int fd, unsigned long long *v1, unsigned long long *v2) +{ + /* two numbers in this sysfs file, either + * NNN (NNN) + * or + * NNN / NNN + */ + char buf[80]; + int n; + char *ep, *ep2; + + lseek(fd, 0, 0); + n = read(fd, buf, sizeof(buf)); + if (n <= 0) + return -2; + buf[n] = 0; + *v1 = strtoull(buf, &ep, 0); + if (ep == buf || (*ep != 0 && *ep != '\n' && *ep != ' ')) + return -1; + while (*ep == ' ' || *ep == '/' || *ep == '(') + ep++; + *v2 = strtoull(ep, &ep2, 0); + if (ep2 == ep || (*ep2 != 0 && *ep2 != '\n' && *ep2 != ' ' && *ep2 != ')')) { + *v2 = *v1; + return 1; + } + return 2; +} + +int sysfs_get_two(struct mdinfo *sra, struct mdinfo *dev, + char *name, unsigned long long *v1, unsigned long long *v2) +{ + int n; + int fd; + + fd = sysfs_get_fd(sra, dev, name); + if (fd < 0) + return -1; + n = sysfs_fd_get_two(fd, v1, v2); + close(fd); + return n; +} + int sysfs_fd_get_str(int fd, char *val, int size) { int n; |