summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-10-09 13:54:59 +1100
committerNeilBrown <neilb@suse.de>2012-10-09 13:54:59 +1100
commite0ab37a3aedc285525cc8fdf14a64c4d586cf106 (patch)
tree2b4b7658bfe0039b91d926ad38c9d2744d55794c
parentfffaf1ff484c54defd79d608adab6ec615c6e3b7 (diff)
Grow: allow --grow --continue to work for native metadata.
As it was the code would crash due to "mdstat" being NULL. Code is now more sane, but hasn't been tested on an array that needs to grow. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--Grow.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/Grow.c b/Grow.c
index 29a1c864..5979bb62 100644
--- a/Grow.c
+++ b/Grow.c
@@ -4370,15 +4370,49 @@ int Grow_continue_command(char *devname, int fd,
}
dprintf("Grow continue is run for ");
if (st->ss->external == 0) {
+ int d;
dprintf("native array (%s)\n", devname);
- if (ioctl(fd, GET_ARRAY_INFO, &array) < 0) {
+ if (ioctl(fd, GET_ARRAY_INFO, &array.array) < 0) {
pr_err("%s is not an active md array -"
" aborting\n", devname);
ret_val = 1;
goto Grow_continue_command_exit;
}
content = &array;
- sysfs_init(content, fd, st->devnum);
+ /* Need to load a superblock.
+ * FIXME we should really get what we need from
+ * sysfs
+ */
+ for (d = 0; d < MAX_DISKS; d++) {
+ mdu_disk_info_t disk;
+ char *dv;
+ int err;
+ disk.number = d;
+ if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
+ continue;
+ if (disk.major == 0 && disk.minor == 0)
+ continue;
+ if ((disk.state & (1 << MD_DISK_ACTIVE)) == 0)
+ continue;
+ dv = map_dev(disk.major, disk.minor, 1);
+ if (!dv)
+ continue;
+ fd2 = dev_open(dv, O_RDONLY);
+ if (fd2 < 0)
+ continue;
+ err = st->ss->load_super(st, fd2, NULL);
+ close(fd2);
+ if (err)
+ continue;
+ break;
+ }
+ if (d == MAX_DISKS) {
+ pr_err("Unable to load metadata for %s\n",
+ devname);
+ ret_val = 1;
+ goto Grow_continue_command_exit;
+ }
+ st->ss->getinfo_super(st, content, NULL);
} else {
int container_dev;
@@ -4488,8 +4522,7 @@ int Grow_continue_command(char *devname, int fd,
/* verify that array under reshape is started from
* correct position
*/
- if (verify_reshape_position(content,
- map_name(pers, mdstat->level)) < 0) {
+ if (verify_reshape_position(content, content->array.level) < 0) {
ret_val = 1;
goto Grow_continue_command_exit;
}