summaryrefslogtreecommitdiff
path: root/sysfs.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-07-01 15:10:05 +1000
committerNeilBrown <neilb@suse.de>2013-07-01 15:10:05 +1000
commit2eba849621011a5160b4597f82aa4ed0de7d4e64 (patch)
treebc692036f3889927542d9d0d1b12a8b305e082f9 /sysfs.c
parentefc67e8e9fe430d5833236f16ea287ef363dadc5 (diff)
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.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/sysfs.c b/sysfs.c
index b7d41a57..19d56aa9 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -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;